]> git.proxmox.com Git - qemu.git/blame - thunk.h
added nop test for exception
[qemu.git] / thunk.h
CommitLineData
3ef693a0
FB
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 */
31e31b8a
FB
20#ifndef THUNK_H
21#define THUNK_H
22
23#include <inttypes.h>
7d13299d 24#include "config.h"
34313956
FB
25
26#ifdef HAVE_BYTESWAP_H
31e31b8a 27#include <byteswap.h>
34313956
FB
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({ \
367e86e8
FB
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) )); \
34313956
FB
60})
61
62#endif
31e31b8a 63
24374901 64#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
31e31b8a
FB
65#define BSWAP_NEEDED
66#endif
67
367e86e8 68/* XXX: autoconf */
31e31b8a
FB
69#define TARGET_LONG_BITS 32
70
0d330196 71#if defined(__alpha__) || defined (__ia64__)
31e31b8a
FB
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)
4f101ad7 78#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
31e31b8a
FB
79
80static inline uint16_t bswap16(uint16_t x)
81{
82 return bswap_16(x);
83}
84
85static inline uint32_t bswap32(uint32_t x)
86{
87 return bswap_32(x);
88}
89
90static inline uint64_t bswap64(uint64_t x)
91{
92 return bswap_64(x);
93}
94
bb0ebb1f 95static inline void bswap16s(uint16_t *s)
31e31b8a
FB
96{
97 *s = bswap16(*s);
98}
99
bb0ebb1f 100static inline void bswap32s(uint32_t *s)
31e31b8a
FB
101{
102 *s = bswap32(*s);
103}
104
bb0ebb1f 105static inline void bswap64s(uint64_t *s)
31e31b8a
FB
106{
107 *s = bswap64(*s);
108}
109
110#ifdef BSWAP_NEEDED
111
112static inline uint16_t tswap16(uint16_t s)
113{
114 return bswap16(s);
115}
116
117static inline uint32_t tswap32(uint32_t s)
118{
119 return bswap32(s);
120}
121
122static inline uint64_t tswap64(uint64_t s)
123{
124 return bswap64(s);
125}
126
bb0ebb1f 127static inline void tswap16s(uint16_t *s)
31e31b8a
FB
128{
129 *s = bswap16(*s);
130}
131
bb0ebb1f 132static inline void tswap32s(uint32_t *s)
31e31b8a
FB
133{
134 *s = bswap32(*s);
135}
136
bb0ebb1f 137static inline void tswap64s(uint64_t *s)
31e31b8a
FB
138{
139 *s = bswap64(*s);
140}
141
142#else
143
144static inline uint16_t tswap16(uint16_t s)
145{
146 return s;
147}
148
149static inline uint32_t tswap32(uint32_t s)
150{
151 return s;
152}
153
154static inline uint64_t tswap64(uint64_t s)
155{
156 return s;
157}
158
bb0ebb1f 159static inline void tswap16s(uint16_t *s)
31e31b8a
FB
160{
161}
162
bb0ebb1f 163static inline void tswap32s(uint32_t *s)
31e31b8a
FB
164{
165}
166
bb0ebb1f 167static inline void tswap64s(uint64_t *s)
31e31b8a
FB
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
182typedef int32_t target_long;
183typedef uint32_t target_ulong;
184#elif TARGET_LONG_SIZE == 8
185typedef int64_t target_long;
186typedef uint64_t target_ulong;
187#else
188#error TARGET_LONG_SIZE undefined
189#endif
190
191/* types enums definitions */
192
193typedef 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
215typedef 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... */
228typedef 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
235void thunk_register_struct(int id, const char *name, const argtype *types);
236void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
237const argtype *thunk_convert(void *dst, const void *src,
238 const argtype *type_ptr, int to_host);
0ad041d4 239#ifndef NO_THUNK_TYPE_SIZE
31e31b8a 240
24374901
FB
241extern StructEntry struct_entries[];
242
243static 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
280static 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
0ad041d4
FB
316#endif /* NO_THUNK_TYPE_SIZE */
317
31e31b8a
FB
318unsigned int target_to_host_bitmask(unsigned int x86_mask,
319 bitmask_transtbl * trans_tbl);
320unsigned int host_to_target_bitmask(unsigned int alpha_mask,
321 bitmask_transtbl * trans_tbl);
322
323#endif