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 28#ifndef __ASSEMBLER__ 29 30#define NULL ((void *)0) 31#define BIT(n) (1ul << (n)) 32#define UL_CONST(x) PASTE(x, ul) 33 34#define PACKED __attribute__((packed)) 35#define NORETURN __attribute__((__noreturn__)) 36#define CONST __attribute__((__const__)) 37#define PURE __attribute__((__pure__)) 38#define ALIGN(n) __attribute__((__aligned__(n))) 39#define FASTCALL __attribute__((fastcall)) 40#ifdef __clang__ 41#define VISIBLE /* nothing */ 42#else 43#define VISIBLE __attribute__((externally_visible)) 44#endif 45#define NO_INLINE __attribute__((noinline)) 46#define FORCE_INLINE __attribute__((always_inline)) 47#define SECTION(sec) __attribute__((__section__(sec))) 48#define UNUSED __attribute__((unused)) 49#define USED __attribute__((used)) 50#define FASTCALL __attribute__((fastcall)) 51#define FORCE_O2 __attribute__((optimize("O2"))) 52/** MODIFIES: */ 53void __builtin_unreachable(void); 54#define UNREACHABLE() __builtin_unreachable() 55#define MAY_ALIAS __attribute__((may_alias)) 56 57#define OFFSETOF(type, member) \ 58 __builtin_offsetof(type, member) 59 60#ifdef __GNUC__ 61/* Borrowed from linux/include/linux/compiler.h */ 62#define likely(x) __builtin_expect(!!(x), 1) 63#define unlikely(x) __builtin_expect(!!(x), 0) 64#else 65#define likely(x) (!!(x)) 66#define unlikely(x) (!!(x)) 67#endif 68 69/* need that for compiling with c99 instead of gnu99 */ 70#define asm __asm__ 71 72/* Evaluate a Kconfig-provided configuration setting at compile-time. */ 73#define config_set(macro) _is_set_(macro) 74#define _macrotest_1 , 75#define _is_set_(value) _is_set__(_macrotest_##value) 76#define _is_set__(comma) _is_set___(comma 1, 0) 77#define _is_set___(_, v, ...) v 78 79/* Check the existence of a configuration setting, returning one value if it 80 * exists and a different one if it does not */ 81#define config_ternary(macro, true, false) _config_ternary(macro, true, false) 82#define _config_ternary(value, true, false) _config_ternary_(_macrotest_##value, true, false) 83#define _config_ternary_(comma, true, false) _config_ternary__(comma true, false) 84#define _config_ternary__(_, v, ...) v 85 86/** MODIFIES: 87 FNSPEC 88 halt_spec: "\<Gamma> \<turnstile> {} Call halt_'proc {}" 89*/ 90void halt(void) NORETURN; 91void memzero(void *s, unsigned long n); 92void *memset(void *s, unsigned long c, unsigned long n) VISIBLE; 93void *memcpy(void* ptr_dst, const void* ptr_src, unsigned long n) VISIBLE; 94int PURE strncmp(const char *s1, const char *s2, int n); 95long CONST char_to_long(char c); 96long PURE str_to_long(const char* str); 97 98 99int __builtin_clzl (unsigned long x); 100int __builtin_ctzl (unsigned long x); 101 102#ifdef CONFIG_ARCH_RISCV 103uint32_t __clzsi2(uint32_t x); 104uint32_t __ctzsi2(uint32_t x); 105uint32_t __clzdi2(uint64_t x); 106uint32_t __ctzdi2(uint64_t x); 107#endif 108/** MODIFIES: */ 109/** DONT_TRANSLATE */ 110/** FNSPEC clzl_spec: 111 "\<forall>s. \<Gamma> \<turnstile> 112 {\<sigma>. s = \<sigma> \<and> x_' s \<noteq> 0 } 113 \<acute>ret__long :== PROC clzl(\<acute>x) 114 \<lbrace> \<acute>ret__long = of_nat (word_clz (x_' s)) \<rbrace>" 115*/ 116static inline long 117CONST clzl(unsigned long x) 118{ 119 return __builtin_clzl(x); 120} 121 122/** MODIFIES: */ 123/** DONT_TRANSLATE */ 124/** FNSPEC ctzl_spec: 125 "\<forall>s. \<Gamma> \<turnstile> 126 {\<sigma>. s = \<sigma> \<and> x_' s \<noteq> 0 } 127 \<acute>ret__long :== PROC ctzl(\<acute>x) 128 \<lbrace> \<acute>ret__long = of_nat (word_ctz (x_' s)) \<rbrace>" 129*/ 130static inline long 131CONST ctzl(unsigned long x) 132{ 133 return __builtin_ctzl(x); 134} 135 136#define CTZL(x) __builtin_ctzl(x) 137 138int __builtin_popcountl (unsigned long x); 139 140/** DONT_TRANSLATE */ 141static inline long 142CONST popcountl(unsigned long mask) 143{ 144#ifndef __POPCNT__ 145 unsigned int count; // c accumulates the total bits set in v 146 for (count = 0; mask; count++) { 147 mask &= mask - 1; // clear the least significant bit set 148 } 149 150 return count; 151#else 152 return __builtin_popcountl(mask); 153#endif 154} 155 156#define POPCOUNTL(x) popcountl(x) 157 158/* Can be used to insert padding to the next L1 cache line boundary */ 159#define PAD_TO_NEXT_CACHE_LN(used) char padding[L1_CACHE_LINE_SIZE - ((used) % L1_CACHE_LINE_SIZE)] 160 161#else /* __ASSEMBLER__ */ 162 163/* Some assemblers don't recognise ul (unsigned long) suffix */ 164#define BIT(n) (1 << (n)) 165#define UL_CONST(x) x 166 167#endif /* !__ASSEMBLER__ */ 168#endif /* __UTIL_H */ 169