1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
15 
16 int memcmp(const void *a, const void *b, size_t n);
17 
18 int strncmp(const char *a, const char *b, size_t n);
19 
20 #define ctz(x) __builtin_ctz(x)
21 
22 /* Compatibility with old compilers */
23 #ifndef __has_builtin
24 #define __has_builtin(x) 0
25 #endif
26 
27 /**
28  * Check whether the value `v` is aligned to the boundary `a`,
29  * with `a` power of 2.
30  */
31 #if __has_builtin(__builtin_is_aligned)
32 #define is_aligned(v, a) __builtin_is_aligned((v), (a))
33 #else
34 #define is_aligned(v, a) (((uintptr_t)(v) & ((a)-1)) == 0)
35 #endif
36 
37 /**
38  * Align up the value `v` to the boundary `a`, with `a` power of 2.
39  */
40 #if __has_builtin(__builtin_align_up)
41 #define align_up(v, a) __builtin_align_up((v), (a))
42 #else
43 #define align_up(v, a) (((uintptr_t)(v) + ((a)-1)) & ~((a)-1))
44 #endif
45 
46 /**
47  * Align down the value `v` to the boundary `a`, with `a` power of 2.
48  */
49 #if __has_builtin(__builtin_align_down)
50 #define align_down(v, a) __builtin_align_down((v), (a))
51 #else
52 #define align_down(v, a) ((uintptr_t)(v) & ~((a)-1))
53 #endif
54 
55 #ifndef be16toh
56 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
57 
58 #define be16toh(v) __builtin_bswap16(v)
59 #define be32toh(v) __builtin_bswap32(v)
60 #define be64toh(v) __builtin_bswap64(v)
61 
62 #define htobe16(v) __builtin_bswap16(v)
63 #define htobe32(v) __builtin_bswap32(v)
64 #define htobe64(v) __builtin_bswap64(v)
65 
66 #define le16toh(v) (v)
67 #define le32toh(v) (v)
68 #define le64toh(v) (v)
69 
70 #define htole16(v) (v)
71 #define htole32(v) (v)
72 #define htole64(v) (v)
73 
74 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
75 
76 #define be16toh(v) (v)
77 #define be32toh(v) (v)
78 #define be64toh(v) (v)
79 
80 #define htobe16(v) (v)
81 #define htobe32(v) (v)
82 #define htobe64(v) (v)
83 
84 #define le16toh(v) __builtin_bswap16(v)
85 #define le32toh(v) __builtin_bswap32(v)
86 #define le64toh(v) __builtin_bswap64(v)
87 
88 #define htole16(v) __builtin_bswap16(v)
89 #define htole32(v) __builtin_bswap32(v)
90 #define htole64(v) __builtin_bswap64(v)
91 
92 #else
93 
94 /*
95  * __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ &&
96  * __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
97  */
98 
99 #error "Unsupported byte order"
100 
101 #endif
102 #endif
103