spandsp 3.0.0
unaligned.h
Go to the documentation of this file.
1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * unaligned.h - Cross platform unaligned data access
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2006, 2022 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26/*! \file */
27
28#if !defined(_SPANDSP_UNALIGNED_H_)
29#define _SPANDSP_UNALIGNED_H_
30
31#if defined(__cplusplus)
32extern "C"
33{
34#endif
35
36#if defined(_MSC_VER)
37#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
38
39PACK(struct __dealign_uint16 { uint16_t datum; };)
40PACK(struct __dealign_uint32 { uint32_t datum; };)
41PACK(struct __dealign_uint64 { uint64_t datum; };)
42#endif
43
44#if defined(__GNUC__) || defined(__clang__)
45struct __dealign_uint16 { uint16_t datum; } __attribute__((packed));
46struct __dealign_uint32 { uint32_t datum; } __attribute__((packed));
47struct __dealign_uint64 { uint64_t datum; } __attribute__((packed));
48#endif
49
50#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
51/* If we just tell GCC what's going on, we can trust it to behave optimally */
52static __inline__ uint64_t get_unaligned_uint64(const void *p)
53{
54 const struct __dealign_uint64 *pp = (const struct __dealign_uint64 *) p;
55
56 return pp->datum;
57}
58/*- End of function --------------------------------------------------------*/
59
60static __inline__ void put_unaligned_uint64(void *p, uint32_t datum)
61{
62 struct __dealign_uint64 *pp = (struct __dealign_uint64 *) p;
63
64 pp->datum = datum;
65}
66/*- End of function --------------------------------------------------------*/
67
68static __inline__ uint64_t get_net_unaligned_uint64(const void *p)
69{
70 const struct __dealign_uint64 *pp = (const struct __dealign_uint64 *) p;
71
72#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
73 return pp->datum;
74#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
75 return __builtin_bswap64(pp->datum);
76#endif
77}
78/*- End of function --------------------------------------------------------*/
79
80static __inline__ void put_net_unaligned_uint64(void *p, uint64_t datum)
81{
82 struct __dealign_uint64 *pp = (struct __dealign_uint64 *) p;
83
84#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
85 pp->datum = datum;
86#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
87 pp->datum = __builtin_bswap64(datum);
88#endif
89}
90/*- End of function --------------------------------------------------------*/
91
92static __inline__ uint32_t get_unaligned_uint32(const void *p)
93{
94 const struct __dealign_uint32 *pp = (const struct __dealign_uint32 *) p;
95
96 return pp->datum;
97}
98/*- End of function --------------------------------------------------------*/
99
100static __inline__ void put_unaligned_uint32(void *p, uint32_t datum)
101{
102 struct __dealign_uint32 *pp = (struct __dealign_uint32 *) p;
103
104 pp->datum = datum;
105}
106/*- End of function --------------------------------------------------------*/
107
108static __inline__ uint32_t get_net_unaligned_uint32(const void *p)
109{
110 const struct __dealign_uint32 *pp = (const struct __dealign_uint32 *) p;
111
112#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
113 return pp->datum;
114#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
115 return __builtin_bswap32(pp->datum);
116#endif
117}
118/*- End of function --------------------------------------------------------*/
119
120static __inline__ void put_net_unaligned_uint32(void *p, uint32_t datum)
121{
122 struct __dealign_uint32 *pp = (struct __dealign_uint32 *) p;
123
124#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
125 pp->datum = datum;
126#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
127 pp->datum = __builtin_bswap32(datum);
128#endif
129}
130/*- End of function --------------------------------------------------------*/
131
132static __inline__ uint16_t get_unaligned_uint16(const void *p)
133{
134 const struct __dealign_uint16 *pp = (const struct __dealign_uint16 *) p;
135
136 return pp->datum;
137}
138/*- End of function --------------------------------------------------------*/
139
140static __inline__ void put_unaligned_uint16(void *p, uint16_t datum)
141{
142 struct __dealign_uint16 *pp = (struct __dealign_uint16 *) p;
143
144 pp->datum = datum;
145}
146/*- End of function --------------------------------------------------------*/
147
148static __inline__ uint16_t get_net_unaligned_uint16(const void *p)
149{
150 const struct __dealign_uint16 *pp = (const struct __dealign_uint16 *) p;
151
152#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
153 return pp->datum;
154#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
155 return __builtin_bswap16(pp->datum);
156#endif
157}
158/*- End of function --------------------------------------------------------*/
159
160static __inline__ void put_net_unaligned_uint16(void *p, uint16_t datum)
161{
162 struct __dealign_uint16 *pp = (struct __dealign_uint16 *) p;
163
164#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
165 pp->datum = datum;
166#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
167 pp->datum = __builtin_bswap16(datum);
168#endif
169}
170/*- End of function --------------------------------------------------------*/
171
172#elif defined(SOLARIS) && defined(__sparc__)
173
174static __inline__ uint64_t get_unaligned_uint64(const void *p)
175{
176 const uint8_t *cp = p;
177
178 return (cp[0] << 56) | (cp[1] << 48) | (cp[2] << 40) | (cp[3] << 32) | (cp[4] << 24) | (cp[5] << 16) | (cp[6] << 8) | cp[7];
179}
180/*- End of function --------------------------------------------------------*/
181
182static __inline__ void put_unaligned_uint64(void *p, uint64_t datum)
183{
184 const uint8_t *cp = p;
185
186 cp[0] = datum >> 56;
187 cp[1] = datum >> 48;
188 cp[2] = datum >> 40;
189 cp[3] = datum >> 32;
190 cp[4] = datum >> 24;
191 cp[5] = datum >> 16;
192 cp[6] = datum >> 8;
193 cp[7] = datum;
194}
195/*- End of function --------------------------------------------------------*/
196
197static __inline__ uint32_t get_unaligned_uint32(const void *p)
198{
199 const uint8_t *cp = p;
200
201 return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | cp[3];
202}
203/*- End of function --------------------------------------------------------*/
204
205static __inline__ void put_unaligned_uint32(void *p, uint32_t datum)
206{
207 const uint8_t *cp = p;
208
209 cp[0] = datum >> 24;
210 cp[1] = datum >> 16;
211 cp[2] = datum >> 8;
212 cp[3] = datum;
213}
214/*- End of function --------------------------------------------------------*/
215
216static __inline__ uint16_t get_unaligned_uint16(const void *p)
217{
218 const uint8_t *cp = p;
219
220 return (cp[0] << 8) | cp[1];
221}
222/*- End of function --------------------------------------------------------*/
223
224static __inline__ void put_unaligned_uint16(void *p, uint16_t datum)
225{
226 uint8_t *cp = p;
227
228 cp[0] = datum >> 8;
229 cp[1] = datum;
230}
231/*- End of function --------------------------------------------------------*/
232
233#else
234
235/* The generic case. Assume we can handle direct load/store. */
236#define get_unaligned_uint64(p) (*((uint64_t *) (p)))
237#define put_unaligned_uint64(p,d) do { uint64_t *__P = (p); *__P = d; } while(0)
238#define get_net_unaligned_uint64(p) (*((uint64_t *) (p)))
239#define put_net_unaligned_uint64(p,d) do { uint64_t *__P = (p); *__P = d; } while(0)
240#define get_unaligned_uint32(p) (*((uint32_t *) (p)))
241#define put_unaligned_uint32(p,d) do { uint32_t *__P = (p); *__P = d; } while(0)
242#define get_net_unaligned_uint32(p) (*((uint32_t *) (p)))
243#define put_net_unaligned_uint32(p,d) do { uint32_t *__P = (p); *__P = d; } while(0)
244#define get_unaligned_uint16(p) (*((uint16_t *) (p)))
245#define put_unaligned_uint16(p,d) do { uint16_t *__P = (p); *__P = d; } while(0)
246#define get_net_unaligned_uint16(p) (*((uint16_t *) (p)))
247#define put_net_unaligned_uint16(p,d) do { uint16_t *__P = (p); *__P = d; } while(0)
248#endif
249
250#if defined(__cplusplus)
251}
252#endif
253
254#endif
255/*- End of file ------------------------------------------------------------*/