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