Statistics
| Branch: | Revision:

root / thunk.h @ a412ac57

History | View | Annotate | Download (7.1 kB)

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