]> git.proxmox.com Git - qemu.git/blob - thunk.h
fixed inline pb
[qemu.git] / thunk.h
1 /*
2 * Generic thunking code to convert data between host and target CPU
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #ifndef THUNK_H
21 #define THUNK_H
22
23 #include <inttypes.h>
24 #include "config.h"
25
26 #ifdef HAVE_BYTESWAP_H
27 #include <byteswap.h>
28 #else
29
30 #define bswap_16(x) \
31 ({ \
32 uint16_t __x = (x); \
33 ((uint16_t)( \
34 (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
35 (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
36 })
37
38 #define bswap_32(x) \
39 ({ \
40 uint32_t __x = (x); \
41 ((uint32_t)( \
42 (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
43 (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
44 (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
45 (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
46 })
47
48 #define bswap_64(x) \
49 ({ \
50 uint64_t __x = (x); \
51 ((uint64_t)( \
52 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
53 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
54 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
55 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
56 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
57 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
58 (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
59 (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
60 })
61
62 #endif
63
64 #if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
65 #define BSWAP_NEEDED
66 #endif
67
68 /* XXX: autoconf */
69 #define TARGET_LONG_BITS 32
70
71 #if defined(__alpha__) || defined (__ia64__)
72 #define HOST_LONG_BITS 64
73 #else
74 #define HOST_LONG_BITS 32
75 #endif
76
77 #define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
78 #define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
79
80 static inline uint16_t bswap16(uint16_t x)
81 {
82 return bswap_16(x);
83 }
84
85 static inline uint32_t bswap32(uint32_t x)
86 {
87 return bswap_32(x);
88 }
89
90 static inline uint64_t bswap64(uint64_t x)
91 {
92 return bswap_64(x);
93 }
94
95 static inline void bswap16s(uint16_t *s)
96 {
97 *s = bswap16(*s);
98 }
99
100 static inline void bswap32s(uint32_t *s)
101 {
102 *s = bswap32(*s);
103 }
104
105 static inline void bswap64s(uint64_t *s)
106 {
107 *s = bswap64(*s);
108 }
109
110 #ifdef BSWAP_NEEDED
111
112 static inline uint16_t tswap16(uint16_t s)
113 {
114 return bswap16(s);
115 }
116
117 static inline uint32_t tswap32(uint32_t s)
118 {
119 return bswap32(s);
120 }
121
122 static inline uint64_t tswap64(uint64_t s)
123 {
124 return bswap64(s);
125 }
126
127 static inline void tswap16s(uint16_t *s)
128 {
129 *s = bswap16(*s);
130 }
131
132 static inline void tswap32s(uint32_t *s)
133 {
134 *s = bswap32(*s);
135 }
136
137 static inline void tswap64s(uint64_t *s)
138 {
139 *s = bswap64(*s);
140 }
141
142 #else
143
144 static inline uint16_t tswap16(uint16_t s)
145 {
146 return s;
147 }
148
149 static inline uint32_t tswap32(uint32_t s)
150 {
151 return s;
152 }
153
154 static inline uint64_t tswap64(uint64_t s)
155 {
156 return s;
157 }
158
159 static inline void tswap16s(uint16_t *s)
160 {
161 }
162
163 static inline void tswap32s(uint32_t *s)
164 {
165 }
166
167 static inline void tswap64s(uint64_t *s)
168 {
169 }
170
171 #endif
172
173 #if TARGET_LONG_SIZE == 4
174 #define tswapl(s) tswap32(s)
175 #define tswapls(s) tswap32s((uint32_t *)(s))
176 #else
177 #define tswapl(s) tswap64(s)
178 #define tswapls(s) tswap64s((uint64_t *)(s))
179 #endif
180
181 #if TARGET_LONG_SIZE == 4
182 typedef int32_t target_long;
183 typedef uint32_t target_ulong;
184 #elif TARGET_LONG_SIZE == 8
185 typedef int64_t target_long;
186 typedef uint64_t target_ulong;
187 #else
188 #error TARGET_LONG_SIZE undefined
189 #endif
190
191 /* types enums definitions */
192
193 typedef enum argtype {
194 TYPE_NULL,
195 TYPE_CHAR,
196 TYPE_SHORT,
197 TYPE_INT,
198 TYPE_LONG,
199 TYPE_ULONG,
200 TYPE_PTRVOID, /* pointer on unknown data */
201 TYPE_LONGLONG,
202 TYPE_ULONGLONG,
203 TYPE_PTR,
204 TYPE_ARRAY,
205 TYPE_STRUCT,
206 } argtype;
207
208 #define MK_PTR(type) TYPE_PTR, type
209 #define MK_ARRAY(type, size) TYPE_ARRAY, size, type
210 #define MK_STRUCT(id) TYPE_STRUCT, id
211
212 #define THUNK_TARGET 0
213 #define THUNK_HOST 1
214
215 typedef struct {
216 /* standard struct handling */
217 const argtype *field_types;
218 int nb_fields;
219 int *field_offsets[2];
220 /* special handling */
221 void (*convert[2])(void *dst, const void *src);
222 int size[2];
223 int align[2];
224 const char *name;
225 } StructEntry;
226
227 /* Translation table for bitmasks... */
228 typedef struct bitmask_transtbl {
229 unsigned int x86_mask;
230 unsigned int x86_bits;
231 unsigned int alpha_mask;
232 unsigned int alpha_bits;
233 } bitmask_transtbl;
234
235 void thunk_register_struct(int id, const char *name, const argtype *types);
236 void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
237 const argtype *thunk_convert(void *dst, const void *src,
238 const argtype *type_ptr, int to_host);
239 #ifndef NO_THUNK_TYPE_SIZE
240
241 extern StructEntry struct_entries[];
242
243 static inline int thunk_type_size(const argtype *type_ptr, int is_host)
244 {
245 int type, size;
246 const StructEntry *se;
247
248 type = *type_ptr;
249 switch(type) {
250 case TYPE_CHAR:
251 return 1;
252 case TYPE_SHORT:
253 return 2;
254 case TYPE_INT:
255 return 4;
256 case TYPE_LONGLONG:
257 case TYPE_ULONGLONG:
258 return 8;
259 case TYPE_LONG:
260 case TYPE_ULONG:
261 case TYPE_PTRVOID:
262 case TYPE_PTR:
263 if (is_host) {
264 return HOST_LONG_SIZE;
265 } else {
266 return TARGET_LONG_SIZE;
267 }
268 break;
269 case TYPE_ARRAY:
270 size = type_ptr[1];
271 return size * thunk_type_size(type_ptr + 2, is_host);
272 case TYPE_STRUCT:
273 se = struct_entries + type_ptr[1];
274 return se->size[is_host];
275 default:
276 return -1;
277 }
278 }
279
280 static inline int thunk_type_align(const argtype *type_ptr, int is_host)
281 {
282 int type;
283 const StructEntry *se;
284
285 type = *type_ptr;
286 switch(type) {
287 case TYPE_CHAR:
288 return 1;
289 case TYPE_SHORT:
290 return 2;
291 case TYPE_INT:
292 return 4;
293 case TYPE_LONGLONG:
294 case TYPE_ULONGLONG:
295 return 8;
296 case TYPE_LONG:
297 case TYPE_ULONG:
298 case TYPE_PTRVOID:
299 case TYPE_PTR:
300 if (is_host) {
301 return HOST_LONG_SIZE;
302 } else {
303 return TARGET_LONG_SIZE;
304 }
305 break;
306 case TYPE_ARRAY:
307 return thunk_type_align(type_ptr + 2, is_host);
308 case TYPE_STRUCT:
309 se = struct_entries + type_ptr[1];
310 return se->align[is_host];
311 default:
312 return -1;
313 }
314 }
315
316 #endif /* NO_THUNK_TYPE_SIZE */
317
318 unsigned int target_to_host_bitmask(unsigned int x86_mask,
319 bitmask_transtbl * trans_tbl);
320 unsigned int host_to_target_bitmask(unsigned int alpha_mask,
321 bitmask_transtbl * trans_tbl);
322
323 #endif