xref: /openbsd-src/gnu/usr.bin/binutils/gdb/rdi-share/angel_endian.h (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /*
2b725ae77Skettenis  * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3b725ae77Skettenis  *
4b725ae77Skettenis  * This software may be freely used, copied, modified, and distributed
5b725ae77Skettenis  * provided that the above copyright notice is preserved in all copies of the
6b725ae77Skettenis  * software.
7b725ae77Skettenis  */
8b725ae77Skettenis 
9b725ae77Skettenis /* -*-C-*-
10b725ae77Skettenis  *
11*63addd46Skettenis  * $Revision: 1.3 $
12*63addd46Skettenis  *     $Date: 2004/12/27 14:00:53 $
13b725ae77Skettenis  *
14b725ae77Skettenis  *
15b725ae77Skettenis  * angel_endian.h - target endianness independent read/write primitives.
16b725ae77Skettenis  */
17b725ae77Skettenis 
18b725ae77Skettenis #ifndef angel_endian_h
19b725ae77Skettenis #define angel_endian_h
20b725ae77Skettenis 
21b725ae77Skettenis /*
22b725ae77Skettenis  * The endianness of the data being processed needs to be known, but
23b725ae77Skettenis  * the host endianness is not required (since the data is constructed
24b725ae77Skettenis  * using bytes).  At the moment these are provided as macros. This
25b725ae77Skettenis  * gives the compiler freedom in optimising individual calls. However,
26b725ae77Skettenis  * if space is at a premium then functions should be provided.
27b725ae77Skettenis  *
28b725ae77Skettenis  * NOTE: These macros assume that the data has been packed in the same format
29b725ae77Skettenis  *       as the packing on the build host. If this is not the case then
30b725ae77Skettenis  *       the wrong addresses could be used when dealing with structures.
31b725ae77Skettenis  *
32b725ae77Skettenis  */
33b725ae77Skettenis 
34b725ae77Skettenis /*
35b725ae77Skettenis  * For all the following routines the target endianness is defined by the
36b725ae77Skettenis  * following boolean definitions.
37b725ae77Skettenis  */
38b725ae77Skettenis #define BE (1 == 1) /* TRUE  : big-endian */
39b725ae77Skettenis #define LE (1 == 0) /* FALSE : little-endian */
40b725ae77Skettenis 
41b725ae77Skettenis /*
42b725ae77Skettenis  * The following type definitions are used by the endianness converting
43b725ae77Skettenis  * macros.
44b725ae77Skettenis  */
45b725ae77Skettenis typedef unsigned char U8;
46b725ae77Skettenis typedef U8 *P_U8;
47b725ae77Skettenis typedef const U8 *CP_U8;
48b725ae77Skettenis 
49b725ae77Skettenis typedef unsigned short U16;
50b725ae77Skettenis typedef U16 *P_U16;
51b725ae77Skettenis 
52b725ae77Skettenis typedef unsigned int U32;
53b725ae77Skettenis typedef U32 *P_U32;
54b725ae77Skettenis 
55b725ae77Skettenis /*
56b725ae77Skettenis  * If the endianness of the host and target are known (fixed) and the same
57b725ae77Skettenis  * then the following macro definitions can be used. These just directly copy
58b725ae77Skettenis  * the data.
59b725ae77Skettenis  *
60b725ae77Skettenis  * #define READ(e,a)       (a)
61b725ae77Skettenis  * #define WRITE(e,a,v)    ((a) = (v))
62b725ae77Skettenis  * #define PREAD(e,a)      (a)
63b725ae77Skettenis  * #define PWRITE(e,a,v)   (*(a) = (v))
64b725ae77Skettenis  */
65b725ae77Skettenis 
66b725ae77Skettenis /*
67b725ae77Skettenis  * These macros assume that a byte (char) is 8bits in size, and that the
68b725ae77Skettenis  * endianness is not important when reading or writing bytes.
69b725ae77Skettenis  */
70b725ae77Skettenis #define PUT8(a,v)       (*((P_U8)(a)) = (U8)(v))
71b725ae77Skettenis #define PUT16LE(a,v)    (PUT8(a,((v) & 0xFF)), \
72b725ae77Skettenis                          PUT8((((P_U8)(a)) + sizeof(char)),((v) >> 8)))
73b725ae77Skettenis #define PUT16BE(a,v)    (PUT8(a,((v) >> 8)), \
74b725ae77Skettenis                          PUT8((((P_U8)(a)) + sizeof(char)),((v) & 0xFF)))
75b725ae77Skettenis #define PUT32LE(a,v)    (PUT16LE(a,v), \
76b725ae77Skettenis                          PUT16LE((((P_U8)(a)) + sizeof(short)),((v) >> 16)))
77b725ae77Skettenis #define PUT32BE(a,v)    (PUT16BE(a,((v) >> 16)), \
78b725ae77Skettenis                          PUT16BE((((P_U8)(a)) + sizeof(short)),v))
79b725ae77Skettenis 
80b725ae77Skettenis #define GET8(a)     (*((CP_U8)(a)))
81b725ae77Skettenis #define GET16LE(a)  (GET8(a) | (((U16)GET8(((CP_U8)(a)) + sizeof(char))) << 8))
82b725ae77Skettenis #define GET16BE(a)  ((((U16)GET8(a)) << 8) | GET8(((CP_U8)(a)) + sizeof(char)))
83b725ae77Skettenis #define GET32LE(a)  (GET16LE(a) | \
84b725ae77Skettenis                      (((U32)GET16LE(((CP_U8)(a)) + sizeof(short))) << 16))
85b725ae77Skettenis #define GET32BE(a)  ((((U32)GET16BE(a)) << 16) | \
86b725ae77Skettenis                      GET16BE(((CP_U8)(a)) + sizeof(short)))
87b725ae77Skettenis 
88b725ae77Skettenis /*
89b725ae77Skettenis  * These macros simplify the code in respect to reading and writing the
90b725ae77Skettenis  * correct size data when dealing with endianness. "e" is TRUE if we are
91b725ae77Skettenis  * dealing with big-endian data, FALSE if we are dealing with little-endian.
92b725ae77Skettenis  */
93b725ae77Skettenis 
94b725ae77Skettenis /* void WRITE(int endianness, void *address, unsigned value); */
95b725ae77Skettenis 
96b725ae77Skettenis #define WRITE16(e,a,v) ((e) ? PUT16BE(&(a),v) : PUT16LE(&(a),v))
97b725ae77Skettenis #define WRITE32(e,a,v) ((e) ? PUT32BE(&(a),v) : PUT32LE(&(a),v))
98b725ae77Skettenis #define WRITE(e,a,v)   ((sizeof(v) == sizeof(char)) ? \
99b725ae77Skettenis                         PUT8(&(a),v) : ((sizeof(v) == sizeof(short)) ? \
100b725ae77Skettenis                                         WRITE16(e,a,v) : WRITE32(e,a,v)))
101b725ae77Skettenis 
102b725ae77Skettenis /* unsigned READ(int endianness, void *address) */
103b725ae77Skettenis #define READ16(e,a) ((e) ? GET16BE(&(a)) : GET16LE(&(a)))
104b725ae77Skettenis #define READ32(e,a) ((e) ? GET32BE(&(a)) : GET32LE(&(a)))
105b725ae77Skettenis #define READ(e,a) ((sizeof(a) == sizeof(char)) ? \
106b725ae77Skettenis                    GET8((CP_U8)&(a)) : ((sizeof(a) == sizeof(short)) ? \
107b725ae77Skettenis                                        READ16(e,a) : READ32(e,a)))
108b725ae77Skettenis 
109b725ae77Skettenis /* void PWRITE(int endianness, void *address, unsigned value); */
110b725ae77Skettenis #define PWRITE16(e,a,v) ((e) ? PUT16BE(a,v) : PUT16LE(a,v))
111b725ae77Skettenis #define PWRITE32(e,a,v) ((e) ? PUT32BE(a,v) : PUT32LE(a,v))
112b725ae77Skettenis #define PWRITE(e,a,v)   ((sizeof(v) == sizeof(char)) ? \
113b725ae77Skettenis                          PUT8(a,v) : ((sizeof(v) == sizeof(short)) ? \
114b725ae77Skettenis                                       PWRITE16(e,a,v) : PWRITE32(e,a,v)))
115b725ae77Skettenis 
116b725ae77Skettenis /* unsigned PREAD(int endianness, void *address) */
117b725ae77Skettenis #define PREAD16(e,a) ((e) ? GET16BE(a) : GET16LE(a))
118b725ae77Skettenis #define PREAD32(e,a) ((e) ? GET32BE(a) : GET32LE(a))
119b725ae77Skettenis #define PREAD(e,a) ((sizeof(*(a)) == sizeof(char)) ? \
120b725ae77Skettenis                     GET8((CP_U8)a) : ((sizeof(*(a)) == sizeof(short)) ? \
121b725ae77Skettenis                                      PREAD16(e,a) : PREAD32(e,a)))
122b725ae77Skettenis 
123b725ae77Skettenis #endif /* !defined(angel_endian_h) */
124b725ae77Skettenis 
125b725ae77Skettenis /* EOF angel_endian.h */
126