• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
8  *   USA; either version 2 of the License, or (at your option) any later
9  *   version; incorporated herein by reference.
10  *
11  * ----------------------------------------------------------------------- */
12 
13 /*
14  * ulint.h
15  *
16  * Basic operations on unaligned, littleendian integers
17  */
18 
19 #ifndef ULINT_H
20 #define ULINT_H
21 
22 #include <inttypes.h>
23 
24 /* These are unaligned, littleendian integer types */
25 
26 typedef uint8_t le8_t;		/*  8-bit byte */
27 typedef uint8_t le16_t[2];	/* 16-bit word */
28 typedef uint8_t le32_t[4];	/* 32-bit dword */
29 
30 /* Read/write these quantities */
31 
read8(le8_t * _p)32 static inline unsigned char read8(le8_t * _p)
33 {
34     return *_p;
35 }
36 
write8(le8_t * _p,uint8_t _v)37 static inline void write8(le8_t * _p, uint8_t _v)
38 {
39     *_p = _v;
40 }
41 
42 #if defined(__i386__) || defined(__x86_64__)
43 
44 /* Littleendian architectures which support unaligned memory accesses */
45 
read16(le16_t * _p)46 static inline unsigned short read16(le16_t * _p)
47 {
48     return *((const uint16_t *)_p);
49 }
50 
write16(le16_t * _p,unsigned short _v)51 static inline void write16(le16_t * _p, unsigned short _v)
52 {
53     *((uint16_t *) _p) = _v;
54 }
55 
read32(le32_t * _p)56 static inline unsigned int read32(le32_t * _p)
57 {
58     return *((const uint32_t *)_p);
59 }
60 
write32(le32_t * _p,uint32_t _v)61 static inline void write32(le32_t * _p, uint32_t _v)
62 {
63     *((uint32_t *) _p) = _v;
64 }
65 
66 #else
67 
68 /* Generic, mostly portable versions */
69 
read16(le16_t * _pp)70 static inline unsigned short read16(le16_t * _pp)
71 {
72     uint8_t *_p = *_pp;
73     uint16_t _v;
74 
75     _v = _p[0];
76     _v |= _p[1] << 8;
77     return _v;
78 }
79 
write16(le16_t * _pp,uint16_t _v)80 static inline void write16(le16_t * _pp, uint16_t _v)
81 {
82     uint8_t *_p = *_pp;
83 
84     _p[0] = _v & 0xFF;
85     _p[1] = (_v >> 8) & 0xFF;
86 }
87 
read32(le32_t * _pp)88 static inline unsigned int read32(le32_t * _pp)
89 {
90     uint8_t *_p = *_pp;
91     uint32_t _v;
92 
93     _v = _p[0];
94     _v |= _p[1] << 8;
95     _v |= _p[2] << 16;
96     _v |= _p[3] << 24;
97     return _v;
98 }
99 
write32(le32_t * _pp,uint32_t _v)100 static inline void write32(le32_t * _pp, uint32_t _v)
101 {
102     uint8_t *_p = *_pp;
103 
104     _p[0] = _v & 0xFF;
105     _p[1] = (_v >> 8) & 0xFF;
106     _p[2] = (_v >> 16) & 0xFF;
107     _p[3] = (_v >> 24) & 0xFF;
108 }
109 
110 #endif
111 
112 #endif /* ULINT_H */
113