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