File: unaligned.h

package info (click to toggle)
vdo 8.3.1.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,536 kB
  • sloc: ansic: 21,023; sh: 349; makefile: 314; perl: 242
file content (137 lines) | stat: -rw-r--r-- 3,868 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright Red Hat
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#ifndef LINUX_UNALIGNED_H
#define LINUX_UNALIGNED_H

#include <asm/byteorder.h>
#include <linux/types.h>

/* Type safe comparison macros, similar to the ones in linux/minmax.h. */

/*
 * If pointers to types are comparable (without dereferencing them and
 * potentially causing side effects) then types are the same.
 */
 #define __typecheck(x, y) \
	(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))

/* 
 * Hack for VDO to replace use of the kernel's __is_constexpr() in __cmp_ macros.
 * VDO cannot use __is_constexpr() due to it relying on a GCC extension to allow sizeof(void).
 */
#define __constcheck(x, y) \
	(__builtin_constant_p(x) && __builtin_constant_p(y))

/* It takes two levels of macro expansion to compose the unique temp names. */
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)

/* Defined in linux/minmax.h */
#define __cmp_op_min <
#define __cmp_op_max >

#define __cmp(op, x, y)	((x) __cmp_op_##op (y) ? (x) : (y))

#define __cmp_once(op, x, y, unique_x, unique_y) \
	__extension__({                          \
		typeof(x) unique_x = (x);        \
		typeof(y) unique_y = (y);        \
		__cmp(op, unique_x, unique_y);   \
	})

#define __careful_cmp(op, x, y)                            \
	__builtin_choose_expr(                             \
		(__typecheck(x, y) && __constcheck(x, y)), \
		__cmp(op, x, y),                           \
		__cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)))

#define min(x, y) __careful_cmp(min, x, y)
#define max(x, y) __careful_cmp(max, x, y)

/* Defined in linux/minmax.h */
#define swap(a, b) \
	do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)

/* Defined in linux/math.h */
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))

/* Defined in asm/unaligned.h */
static inline uint16_t get_unaligned_le16(const void *p)
{
	return __le16_to_cpup((const __le16 *)p);
}

static inline uint32_t get_unaligned_le32(const void *p)
{
	return __le32_to_cpup((const __le32 *)p);
}

static inline uint64_t get_unaligned_le64(const void *p)
{
	return __le64_to_cpup((const __le64 *)p);
}

static inline uint16_t get_unaligned_be16(const void *p)
{
	return __be16_to_cpup((const __be16 *)p);
}

static inline uint32_t get_unaligned_be32(const void *p)
{
	return __be32_to_cpup((const __be32 *)p);
}

static inline uint64_t get_unaligned_be64(const void *p)
{
	return __be64_to_cpup((const __be64 *)p);
}

static inline void put_unaligned_le16(uint16_t val, void *p)
{
	*((__le16 *)p) = __cpu_to_le16(val);
}

static inline void put_unaligned_le32(uint32_t val, void *p)
{
	*((__le32 *)p) = __cpu_to_le32(val);
}

static inline void put_unaligned_le64(uint64_t val, void *p)
{
	*((__le64 *)p) = __cpu_to_le64(val);
}

static inline void put_unaligned_be16(uint16_t val, void *p)
{
	*((__be16 *)p) = __cpu_to_be16(val);
}

static inline void put_unaligned_be32(uint32_t val, void *p)
{
	*((__be32 *)p) = __cpu_to_be32(val);
}

static inline void put_unaligned_be64(uint64_t val, void *p)
{
	*((__be64 *)p) = __cpu_to_be64(val);
}

#endif /* LINUX_UNALIGNED_H */