• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Unaligned memory access functionality.
2    Copyright (C) 2000, 2001, 2002, 2003 Red Hat, Inc.
3    Written by Ulrich Drepper <drepper@redhat.com>, 2001.
4 
5    This program is Open Source software; you can redistribute it and/or
6    modify it under the terms of the Open Software License version 1.0 as
7    published by the Open Source Initiative.
8 
9    You should have received a copy of the Open Software License along
10    with this program; if not, you may obtain a copy of the Open Software
11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13    3001 King Ranch Road, Ukiah, CA 95482.   */
14 
15 #ifndef _UNALIGNED_H
16 #define _UNALIGNED_H	1
17 
18 #include <byteswap.h>
19 #include <endian.h>
20 
21 
22 #ifndef UNALIGNED_ACCESS_CLASS
23 # error "UNALIGNED_ACCESS_CLASS must be defined"
24 #endif
25 
26 
27 /* Macros to convert from the host byte order to that of the object file.  */
28 #if UNALIGNED_ACCESS_CLASS == BYTE_ORDER
29 # define target_bswap_16(n) (n)
30 # define target_bswap_32(n) (n)
31 # define target_bswap_64(n) (n)
32 #else
33 # define target_bswap_16(n) bswap_16 (n)
34 # define target_bswap_32(n) bswap_32 (n)
35 # define target_bswap_64(n) bswap_64 (n)
36 #endif
37 
38 
39 union u_2ubyte_unaligned
40 {
41   uint16_t u;
42   char c[2];
43 } __attribute__((packed));
44 
45 union u_4ubyte_unaligned
46 {
47   uint32_t u;
48   char c[4];
49 } __attribute__((packed));
50 
51 union u_8ubyte_unaligned
52 {
53   uint64_t u;
54   char c[8];
55 } __attribute__((packed));
56 
57 
58 /* Macros to store value at unaligned address.  */
59 #define store_2ubyte_unaligned(ptr, value) \
60   (void) (((union u_2ubyte_unaligned *) (ptr))->u = target_bswap_16 (value))
61 #define store_4ubyte_unaligned(ptr, value) \
62   (void) (((union u_4ubyte_unaligned *) (ptr))->u = target_bswap_32 (value))
63 #define store_8ubyte_unaligned(ptr, value) \
64   (void) (((union u_8ubyte_unaligned *) (ptr))->u = target_bswap_64 (value))
65 
66 
67 /* Macros to add value to unaligned address.  This is a bit more
68    complicated since the value must be read from memory and eventually
69    converted twice.  */
70 #if UNALIGNED_ACCESS_CLASS == BYTE_ORDER
71 # define add_2ubyte_unaligned(ptr, value) \
72   (void) (((union u_2ubyte_unaligned *) (ptr))->u += value)
73 # define add_4ubyte_unaligned(ptr, value) \
74   (void) (((union u_4ubyte_unaligned *) (ptr))->u += value)
75 # define add_8ubyte_unaligned(ptr, value) \
76   (void) (((union u_8ubyte_unaligned *) (ptr))->u += value)
77 #else
78 # define add_2ubyte_unaligned(ptr, value) \
79   do {									      \
80     union u_2ubyte_unaligned *_ptr = (ptr);				      \
81     uint16_t _val = bswap_16 (_ptr->u) + (value);			      \
82     _ptr->u = bswap_16 (_val);						      \
83   } while (0)
84 # define add_4ubyte_unaligned(ptr, value) \
85   do {									      \
86     union u_4ubyte_unaligned *_ptr = (ptr);				      \
87     uint32_t _val = bswap_32 (_ptr->u) + (value);			      \
88     _ptr->u = bswap_32 (_val);						      \
89   } while (0)
90 # define add_8ubyte_unaligned(ptr, value) \
91   do {									      \
92     union u_8ubyte_unaligned *_ptr = (ptr);				      \
93     uint64_t _val = bswap_64 (_ptr->u) + (value);			      \
94     _ptr->u = bswap_64 (_val);						      \
95   } while (0)
96 #endif
97 
98 #endif /* unaligned.h */
99