[go: up one dir, main page]

File: unaligned.h

package info (click to toggle)
drbd-utils 9.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 5,388 kB
  • sloc: ansic: 43,698; xml: 15,968; cpp: 7,783; sh: 3,699; makefile: 1,353; perl: 353
file content (78 lines) | stat: -rw-r--r-- 1,783 bytes parent folder | download | duplicates (12)
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
#ifndef UNALIGNED_H
#define UNALIGNED_H

#include <stdint.h>

#if defined(__i386__) || defined(__x86_64__)
#define UNALIGNED_ACCESS_SUPPORTED
#endif

#ifndef UNALIGNED_ACCESS_SUPPORTED
#warning "Assuming that your architecture can not do unaligned memory accesses."
#warning "Enabling extra code for unaligned memory accesses."
#endif

#ifdef UNALIGNED_ACCESS_SUPPORTED

/* On some architectures the hardware (or microcode) does it */

#define get_unaligned(ptr)		*(ptr)
#define put_unaligned(val, ptr)		*(ptr) = (val)

#else

/* on some architectures we have to do it in program code */

/* Better not use memcpy(). gcc generates broken code an ARM at higher
   optimisation levels
*/

#define __bad_unaligned_access_size() ({			\
	fprintf(stderr, "bad unaligned access. abort()\n");	\
	abort();						\
	})

#define get_unaligned(ptr) ((typeof(*(ptr)))({		\
	typeof(*(ptr)) v;			 	\
	unsigned char *s = (unsigned char*)(ptr);	\
	unsigned char *d = (unsigned char*)&v;		\
	switch (sizeof(v)) {				\
	case 8: *d++ = *s++;				\
		*d++ = *s++;				\
		*d++ = *s++;				\
		*d++ = *s++;				\
	case 4: *d++ = *s++;				\
		*d++ = *s++;				\
	case 2:	*d++ = *s++;				\
	case 1:	*d++ = *s++;				\
		break;					\
	default:					\
		__bad_unaligned_access_size();		\
		break;					\
	}						\
	v; }))


#define put_unaligned(val, ptr) ({			\
	typeof(*(ptr)) v = (val);			\
	unsigned char *d = (unsigned char*)(ptr);	\
	unsigned char *s = (unsigned char*)&v;		\
	switch (sizeof(v)) {				\
	case 8: *d++ = *s++;				\
		*d++ = *s++;				\
		*d++ = *s++;				\
		*d++ = *s++;				\
	case 4: *d++ = *s++;				\
		*d++ = *s++;				\
	case 2:	*d++ = *s++;				\
	case 1:	*d++ = *s++;				\
		break;					\
	default:					\
		__bad_unaligned_access_size();		\
		break;					\
	}						\
	(void)0; })

#endif

#endif