libsidplayfp 1.8.8
sidendian.h
1/*
2 * This file is part of libsidplayfp, a SID player engine.
3 *
4 * Copyright 2000 Simon White
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21
22#ifndef SIDENDIAN_H
23#define SIDENDIAN_H
24
25#ifdef HAVE_CONFIG_H
26# include "config.h"
27#endif
28
29// NOTE: The optimisations in this file rely on the structure of memory
30// e.g. 2 shorts being contained in 1 long. Although these sizes are
31// checked to make sure the optimisation is ok, gcc 2.96 (and above)
32// introduced better optimisations. This results in caching of values
33// in internal registers and therefore writes to ram through the aliases
34// not being reflected in the CPU regs. The use of the volatile keyword
35// fixes this.
36
37#include <stdint.h>
38
39/*
40Labeling:
410 - LO
421 - HI
432 - HILO
443 - HIHI
45*/
46
48// INT16 FUNCTIONS
51inline void endian_16lo8 (uint_least16_t &word, uint8_t byte)
52{
53 word &= 0xff00;
54 word |= byte;
55}
56
58inline uint8_t endian_16lo8 (uint_least16_t word)
59{
60 return (uint8_t) word;
61}
62
64inline void endian_16hi8 (uint_least16_t &word, uint8_t byte)
65{
66 word &= 0x00ff;
67 word |= (uint_least16_t) byte << 8;
68}
69
71inline uint8_t endian_16hi8 (uint_least16_t word)
72{
73 return (uint8_t) (word >> 8);
74}
75
77inline void endian_16swap8 (uint_least16_t &word)
78{
79 uint8_t lo = endian_16lo8 (word);
80 uint8_t hi = endian_16hi8 (word);
81 endian_16lo8 (word, hi);
82 endian_16hi8 (word, lo);
83}
84
86inline uint_least16_t endian_16 (uint8_t hi, uint8_t lo)
87{
88 uint_least16_t word = 0;
89 endian_16lo8 (word, lo);
90 endian_16hi8 (word, hi);
91 return word;
92}
93
95inline void endian_16 (uint8_t ptr[2], uint_least16_t word)
96{
97# if defined(WORDS_BIGENDIAN)
98 ptr[0] = endian_16hi8 (word);
99 ptr[1] = endian_16lo8 (word);
100# else
101 ptr[0] = endian_16lo8 (word);
102 ptr[1] = endian_16hi8 (word);
103# endif
104}
105
106inline void endian_16 (char ptr[2], uint_least16_t word)
107{
108 endian_16 ((uint8_t *) ptr, word);
109}
110
112inline uint_least16_t endian_little16 (const uint8_t ptr[2])
113{
114 return endian_16 (ptr[1], ptr[0]);
115}
116
118inline void endian_little16 (uint8_t ptr[2], uint_least16_t word)
119{
120 ptr[0] = endian_16lo8 (word);
121 ptr[1] = endian_16hi8 (word);
122}
123
125inline uint_least16_t endian_big16 (const uint8_t ptr[2])
126{
127 return endian_16 (ptr[0], ptr[1]);
128}
129
131inline void endian_big16 (uint8_t ptr[2], uint_least16_t word)
132{
133 ptr[0] = endian_16hi8 (word);
134 ptr[1] = endian_16lo8 (word);
135}
136
137
139// INT32 FUNCTIONS
142inline void endian_32lo16 (uint_least32_t &dword, uint_least16_t word)
143{
144 dword &= (uint_least32_t) 0xffff0000;
145 dword |= word;
146}
147
149inline uint_least16_t endian_32lo16 (uint_least32_t dword)
150{
151 return (uint_least16_t) dword & 0xffff;
152}
153
155inline void endian_32hi16 (uint_least32_t &dword, uint_least16_t word)
156{
157 dword &= (uint_least32_t) 0x0000ffff;
158 dword |= (uint_least32_t) word << 16;
159}
160
162inline uint_least16_t endian_32hi16 (uint_least32_t dword)
163{
164 return (uint_least16_t) (dword >> 16);
165}
166
168inline void endian_32lo8 (uint_least32_t &dword, uint8_t byte)
169{
170 dword &= (uint_least32_t) 0xffffff00;
171 dword |= (uint_least32_t) byte;
172}
173
175inline uint8_t endian_32lo8 (uint_least32_t dword)
176{
177 return (uint8_t) dword;
178}
179
181inline void endian_32hi8 (uint_least32_t &dword, uint8_t byte)
182{
183 dword &= (uint_least32_t) 0xffff00ff;
184 dword |= (uint_least32_t) byte << 8;
185}
186
188inline uint8_t endian_32hi8 (uint_least32_t dword)
189{
190 return (uint8_t) (dword >> 8);
191}
192
194inline void endian_32swap16 (uint_least32_t &dword)
195{
196 uint_least16_t lo = endian_32lo16 (dword);
197 uint_least16_t hi = endian_32hi16 (dword);
198 endian_32lo16 (dword, hi);
199 endian_32hi16 (dword, lo);
200}
201
203inline void endian_32swap8 (uint_least32_t &dword)
204{
205 uint_least16_t lo = 0, hi = 0;
206 lo = endian_32lo16 (dword);
207 hi = endian_32hi16 (dword);
208 endian_16swap8 (lo);
209 endian_16swap8 (hi);
210 endian_32lo16 (dword, hi);
211 endian_32hi16 (dword, lo);
212}
213
215inline uint_least32_t endian_32 (uint8_t hihi, uint8_t hilo, uint8_t hi, uint8_t lo)
216{
217 uint_least32_t dword = 0;
218 uint_least16_t word = 0;
219 endian_32lo8 (dword, lo);
220 endian_32hi8 (dword, hi);
221 endian_16lo8 (word, hilo);
222 endian_16hi8 (word, hihi);
223 endian_32hi16 (dword, word);
224 return dword;
225}
226
228inline uint_least32_t endian_little32 (const uint8_t ptr[4])
229{
230 return endian_32 (ptr[3], ptr[2], ptr[1], ptr[0]);
231}
232
234inline void endian_little32 (uint8_t ptr[4], uint_least32_t dword)
235{
236 uint_least16_t word = 0;
237 ptr[0] = endian_32lo8 (dword);
238 ptr[1] = endian_32hi8 (dword);
239 word = endian_32hi16 (dword);
240 ptr[2] = endian_16lo8 (word);
241 ptr[3] = endian_16hi8 (word);
242}
243
245inline uint_least32_t endian_big32 (const uint8_t ptr[4])
246{
247 return endian_32 (ptr[0], ptr[1], ptr[2], ptr[3]);
248}
249
251inline void endian_big32 (uint8_t ptr[4], uint_least32_t dword)
252{
253 uint_least16_t word = 0;
254 word = endian_32hi16 (dword);
255 ptr[1] = endian_16lo8 (word);
256 ptr[0] = endian_16hi8 (word);
257 ptr[2] = endian_32hi8 (dword);
258 ptr[3] = endian_32lo8 (dword);
259}
260
261#endif // SIDENDIAN_H