HPCToolkit
big-endian.h
Go to the documentation of this file.
1 // -*-Mode: C++;-*- // technically C99
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 // This file defines the following macros for converting between host
48 // and big endian format.
49 //
50 // host_to_be_16(uint16_t) --> uint16_t
51 // host_to_be_32(uint32_t) --> uint32_t
52 // host_to_be_64(uint64_t) --> uint64_t
53 //
54 // be_to_host_16(uint16_t) --> uint16_t
55 // be_to_host_32(uint32_t) --> uint32_t
56 // be_to_host_64(uint64_t) --> uint64_t
57 //
58 // We prefer to use <byteswap.h> which usually exists. This file
59 // contains assembler code for the fastest way to swap bytes on a
60 // given architecture. And of course, on a big endian machine, the
61 // conversion functions are just the identity function.
62 //
63 // Notes:
64 // 1. All of the macros expect an unsigned int of the given size.
65 // It's not allowed to do bit operations (&, >>) on floating point,
66 // so if you need to convert a float, convert it to uint32_t first.
67 // Probably the best way to do that is with a union.
68 //
69 // 2. We could use htonl() from <arpa/inet.h> or htobe32() from
70 // <endian.h>. But htonl() has no 64-bit version and <endian.h> is
71 // non-standard. The purpose of this file is to provide a standard
72 // interface that works in all cases and uses the fast assembler code
73 // where possible.
74 
75 //***************************************************************************
76 
77 #ifndef include_big_endian_h
78 #define include_big_endian_h
79 
80 #include <stdint.h>
81 #include <include/hpctoolkit-config.h>
82 
83 //**************************************************
84 // Internal helper functions
85 //**************************************************
86 
87 #ifdef USE_SYSTEM_BYTESWAP
88 
89 #include <byteswap.h>
90 
91 // If <byteswap.h> exists, then it contains assembler code for the
92 // fastest way to swap bytes. We expect this to be the normal case.
93 
94 #define _raw_byte_swap_16(x) bswap_16(x)
95 #define _raw_byte_swap_32(x) bswap_32(x)
96 #define _raw_byte_swap_64(x) bswap_64(x)
97 
98 #else
99 
100 // If not, then a formula of masks and shifts is the fastest way I
101 // (krentel) can find. This is much faster than a loop of shifts (too
102 // serial).
103 
104 #define _raw_byte_swap_16(x) \
105  ( (((x) & 0xff00) >> 8) \
106  | (((x) & 0x00ff) << 8) )
107 
108 #define _raw_byte_swap_32(x) \
109  ( (((x) & 0xff000000) >> 24) \
110  | (((x) & 0x00ff0000) >> 8) \
111  | (((x) & 0x0000ff00) << 8) \
112  | (((x) & 0x000000ff) << 24) )
113 
114 #define _raw_byte_swap_64(x) \
115  ( (((x) & 0xff00000000000000) >> 56) \
116  | (((x) & 0x00ff000000000000) >> 40) \
117  | (((x) & 0x0000ff0000000000) >> 24) \
118  | (((x) & 0x000000ff00000000) >> 8) \
119  | (((x) & 0x00000000ff000000) << 8) \
120  | (((x) & 0x0000000000ff0000) << 24) \
121  | (((x) & 0x000000000000ff00) << 40) \
122  | (((x) & 0x00000000000000ff) << 56) )
123 
124 #endif
125 
126 //**************************************************
127 // Interface functions
128 //**************************************************
129 
130 #ifdef HOST_BIG_ENDIAN
131 
132 // On a big endian machine, the conversion functions are the identity
133 // function.
134 
135 #define host_to_be_16(x) ((uint16_t) (x))
136 #define host_to_be_32(x) ((uint32_t) (x))
137 #define host_to_be_64(x) ((uint64_t) (x))
138 
139 #else
140 
141 // On a little endian machine, we actually swap the bytes.
142 
143 #define host_to_be_16(x) _raw_byte_swap_16((uint16_t) (x))
144 #define host_to_be_32(x) _raw_byte_swap_32((uint32_t) (x))
145 #define host_to_be_64(x) _raw_byte_swap_64((uint64_t) (x))
146 
147 #endif
148 
149 // And in all cases, the conversion from big endian back to host order
150 // is the same as from host to big endian.
151 
152 #define be_to_host_16(x) host_to_be_16(x)
153 #define be_to_host_32(x) host_to_be_32(x)
154 #define be_to_host_64(x) host_to_be_64(x)
155 
156 #endif // include_big_endian_h