vppinfra: add foreach_int macro
[vpp.git] / src / vppinfra / types.h
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16   Copyright (c) 2001-2005 Eliot Dresselhaus
17
18   Permission is hereby granted, free of charge, to any person obtaining
19   a copy of this software and associated documentation files (the
20   "Software"), to deal in the Software without restriction, including
21   without limitation the rights to use, copy, modify, merge, publish,
22   distribute, sublicense, and/or sell copies of the Software, and to
23   permit persons to whom the Software is furnished to do so, subject to
24   the following conditions:
25
26   The above copyright notice and this permission notice shall be
27   included in all copies or substantial portions of the Software.
28
29   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33   LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38 #ifndef included_clib_types_h
39 #define included_clib_types_h
40
41 /* Standard CLIB types. */
42
43 /* Define signed and unsigned 8, 16, 32, and 64 bit types
44    and machine signed/unsigned word for all architectures. */
45 typedef signed char i8;
46 typedef signed short i16;
47
48 /* Avoid conflicts with Linux asm/types.h when __KERNEL__ */
49 #if defined(CLIB_LINUX_KERNEL)
50 /* Linux also defines u8/u16/u32/u64 types. */
51 #include <asm/types.h>
52 #define CLIB_AVOID_CLASH_WITH_LINUX_TYPES
53
54 #else /* ! CLIB_LINUX_KERNEL */
55
56 typedef unsigned char u8;
57 typedef unsigned short u16;
58 #endif /* ! CLIB_LINUX_KERNEL */
59
60 typedef signed __int128 i128;
61 typedef unsigned __int128 u128;
62
63 #if (defined(i386) || (defined(_mips) && __mips != 64) || defined(powerpc) || defined (__SPU__) || defined(__sparc__) || defined(__arm__) || defined (__xtensa__) || defined(__TMS320C6X__))
64 typedef signed int i32;
65 typedef signed long long i64;
66
67 #ifndef CLIB_AVOID_CLASH_WITH_LINUX_TYPES
68 typedef unsigned int u32;
69 typedef unsigned long long u64;
70 #endif /* CLIB_AVOID_CLASH_WITH_LINUX_TYPES */
71
72 #elif defined(alpha) || (defined(_mips) && __mips == 64) ||                   \
73   defined(__x86_64__) || defined(__powerpc64__) || defined(__aarch64__) ||    \
74   (defined(__riscv) && __riscv_xlen == 64)
75 typedef signed int i32;
76 typedef signed long i64;
77
78 #define log2_uword_bits 6
79 #if defined(_mips)
80 #define clib_address_bits _MIPS_SZPTR
81 #else
82 #define clib_address_bits 64
83 #endif
84
85 #ifndef CLIB_AVOID_CLASH_WITH_LINUX_TYPES
86 typedef unsigned int u32;
87 typedef unsigned long u64;
88 #endif /* CLIB_AVOID_CLASH_WITH_LINUX_TYPES */
89
90 #else
91 #error "can't define types"
92 #endif
93
94 /* Default to 32 bit machines with 32 bit addresses. */
95 #ifndef log2_uword_bits
96 #define log2_uword_bits 5
97 #endif
98
99 /* #ifdef's above define log2_uword_bits. */
100 #define uword_bits (1 << log2_uword_bits)
101
102 #ifndef clib_address_bits
103 #define clib_address_bits 32
104 #endif
105
106 /* Word types. */
107 #if uword_bits == 64
108 /* 64 bit word machines. */
109 typedef i64 word;
110 typedef u64 uword;
111 #else
112 /* 32 bit word machines. */
113 typedef i32 word;
114 typedef u32 uword;
115 #endif
116
117 /* integral type of a pointer (used to cast pointers). */
118 #if clib_address_bits == 64
119 typedef u64 clib_address_t;
120 #else
121 typedef u32 clib_address_t;
122 #endif
123
124 #define CLIB_I8_MAX  __INT8_MAX__
125 #define CLIB_I16_MAX __INT16_MAX__
126 #define CLIB_I32_MAX __INT32_MAX__
127 #define CLIB_I64_MAX __INT64_MAX__
128
129 #define CLIB_U8_MAX  __UINT8_MAX__
130 #define CLIB_U16_MAX __UINT16_MAX__
131 #define CLIB_U32_MAX __UINT32_MAX__
132 #define CLIB_U64_MAX __UINT64_MAX__
133
134 #if clib_address_bits == 64
135 #define CLIB_WORD_MAX  CLIB_I64_MAX
136 #define CLIB_UWORD_MAX CLIB_U64_MAX
137 #else
138 #define CLIB_WORD_MAX  CLIB_I32_MAX
139 #define CLIB_UWORD_MAX CLIB_U32_MAX
140 #endif
141
142 /* These are needed to convert between pointers and machine words.
143    MIPS is currently the only machine that can have different sized
144    pointers and machine words (but only when compiling with 64 bit
145    registers and 32 bit pointers). */
146 static inline __attribute__ ((always_inline)) uword
147 pointer_to_uword (const void *p)
148 {
149   return (uword) (clib_address_t) p;
150 }
151
152 static inline __attribute__ ((always_inline)) uword
153 pointer_is_aligned (void *p, uword align)
154 {
155   if ((pointer_to_uword (p) & (align - 1)) == 0)
156     return 1;
157   return 0;
158 }
159
160 #define uword_to_pointer(u,type) ((type) (clib_address_t) (u))
161
162 /* Any type: can be either word or pointer. */
163 typedef word any;
164
165 /* Floating point types. */
166 typedef double f64;
167 typedef float f32;
168
169 typedef __complex__ float cf32;
170 typedef __complex__ double cf64;
171
172 /* Floating point word size. */
173 typedef f64 fword;
174
175 /* Can be used as either {r,l}value, e.g. these both work
176      clib_mem_unaligned (p, u64) = 99
177      clib_mem_unaligned (p, u64) += 99 */
178
179 #define clib_mem_unaligned(pointer,type) \
180   (((struct { CLIB_PACKED (type _data); } *) (pointer))->_data)
181
182 /* Access memory with specified alignment depending on align argument.
183    As with clib_mem_unaligned, may be used as {r,l}value. */
184 #define clib_mem_aligned(addr,type,align)               \
185   (((struct {                                           \
186        type _data                                       \
187        __attribute__ ((aligned (align), packed));       \
188     } *) (addr))->_data)
189
190 typedef u16 u16u __attribute__ ((aligned (1), __may_alias__));
191 typedef u32 u32u __attribute__ ((aligned (1), __may_alias__));
192 typedef u64 u64u __attribute__ ((aligned (1), __may_alias__));
193 typedef i16 i16u __attribute__ ((aligned (1), __may_alias__));
194 typedef i32 i32u __attribute__ ((aligned (1), __may_alias__));
195 typedef i64 i64u __attribute__ ((aligned (1), __may_alias__));
196 typedef word wordu __attribute__ ((aligned (1), __may_alias__));
197 typedef uword uwordu __attribute__ ((aligned (1), __may_alias__));
198
199 #define foreach_int(__var, ...)                                               \
200   for (int __int_array[] = { __VA_ARGS__ }, *__int_ptr = __int_array,         \
201            __var = *__int_ptr;                                                \
202        __int_ptr - ARRAY_LEN (__int_array) < __int_array;                     \
203        __var = *++__int_ptr)
204
205 #endif /* included_clib_types_h */
206
207 /*
208  * fd.io coding-style-patch-verification: ON
209  *
210  * Local Variables:
211  * eval: (c-set-style "gnu")
212  * End:
213  */