Statistics
| Branch: | Revision:

root / thunk.h @ 9da8ba18

History | View | Annotate | Download (5.4 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 abcd5da7 bellard
#include "bswap.h"
27 31e31b8a bellard
28 24374901 bellard
#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
29 31e31b8a bellard
#define BSWAP_NEEDED
30 31e31b8a bellard
#endif
31 31e31b8a bellard
32 367e86e8 bellard
/* XXX: autoconf */
33 31e31b8a bellard
#define TARGET_LONG_BITS 32
34 31e31b8a bellard
35 31e31b8a bellard
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
36 31e31b8a bellard
37 31e31b8a bellard
#ifdef BSWAP_NEEDED
38 31e31b8a bellard
39 31e31b8a bellard
static inline uint16_t tswap16(uint16_t s)
40 31e31b8a bellard
{
41 31e31b8a bellard
    return bswap16(s);
42 31e31b8a bellard
}
43 31e31b8a bellard
44 31e31b8a bellard
static inline uint32_t tswap32(uint32_t s)
45 31e31b8a bellard
{
46 31e31b8a bellard
    return bswap32(s);
47 31e31b8a bellard
}
48 31e31b8a bellard
49 31e31b8a bellard
static inline uint64_t tswap64(uint64_t s)
50 31e31b8a bellard
{
51 31e31b8a bellard
    return bswap64(s);
52 31e31b8a bellard
}
53 31e31b8a bellard
54 bb0ebb1f bellard
static inline void tswap16s(uint16_t *s)
55 31e31b8a bellard
{
56 31e31b8a bellard
    *s = bswap16(*s);
57 31e31b8a bellard
}
58 31e31b8a bellard
59 bb0ebb1f bellard
static inline void tswap32s(uint32_t *s)
60 31e31b8a bellard
{
61 31e31b8a bellard
    *s = bswap32(*s);
62 31e31b8a bellard
}
63 31e31b8a bellard
64 bb0ebb1f bellard
static inline void tswap64s(uint64_t *s)
65 31e31b8a bellard
{
66 31e31b8a bellard
    *s = bswap64(*s);
67 31e31b8a bellard
}
68 31e31b8a bellard
69 31e31b8a bellard
#else
70 31e31b8a bellard
71 31e31b8a bellard
static inline uint16_t tswap16(uint16_t s)
72 31e31b8a bellard
{
73 31e31b8a bellard
    return s;
74 31e31b8a bellard
}
75 31e31b8a bellard
76 31e31b8a bellard
static inline uint32_t tswap32(uint32_t s)
77 31e31b8a bellard
{
78 31e31b8a bellard
    return s;
79 31e31b8a bellard
}
80 31e31b8a bellard
81 31e31b8a bellard
static inline uint64_t tswap64(uint64_t s)
82 31e31b8a bellard
{
83 31e31b8a bellard
    return s;
84 31e31b8a bellard
}
85 31e31b8a bellard
86 bb0ebb1f bellard
static inline void tswap16s(uint16_t *s)
87 31e31b8a bellard
{
88 31e31b8a bellard
}
89 31e31b8a bellard
90 bb0ebb1f bellard
static inline void tswap32s(uint32_t *s)
91 31e31b8a bellard
{
92 31e31b8a bellard
}
93 31e31b8a bellard
94 bb0ebb1f bellard
static inline void tswap64s(uint64_t *s)
95 31e31b8a bellard
{
96 31e31b8a bellard
}
97 31e31b8a bellard
98 31e31b8a bellard
#endif
99 31e31b8a bellard
100 31e31b8a bellard
#if TARGET_LONG_SIZE == 4
101 31e31b8a bellard
#define tswapl(s) tswap32(s)
102 31e31b8a bellard
#define tswapls(s) tswap32s((uint32_t *)(s))
103 31e31b8a bellard
#else
104 31e31b8a bellard
#define tswapl(s) tswap64(s)
105 31e31b8a bellard
#define tswapls(s) tswap64s((uint64_t *)(s))
106 31e31b8a bellard
#endif
107 31e31b8a bellard
108 31e31b8a bellard
#if TARGET_LONG_SIZE == 4
109 31e31b8a bellard
typedef int32_t target_long;
110 31e31b8a bellard
typedef uint32_t target_ulong;
111 31e31b8a bellard
#elif TARGET_LONG_SIZE == 8
112 31e31b8a bellard
typedef int64_t target_long;
113 31e31b8a bellard
typedef uint64_t target_ulong;
114 31e31b8a bellard
#else
115 31e31b8a bellard
#error TARGET_LONG_SIZE undefined
116 31e31b8a bellard
#endif
117 31e31b8a bellard
118 31e31b8a bellard
/* types enums definitions */
119 31e31b8a bellard
120 31e31b8a bellard
typedef enum argtype {
121 31e31b8a bellard
    TYPE_NULL,
122 31e31b8a bellard
    TYPE_CHAR,
123 31e31b8a bellard
    TYPE_SHORT,
124 31e31b8a bellard
    TYPE_INT,
125 31e31b8a bellard
    TYPE_LONG,
126 31e31b8a bellard
    TYPE_ULONG,
127 31e31b8a bellard
    TYPE_PTRVOID, /* pointer on unknown data */
128 31e31b8a bellard
    TYPE_LONGLONG,
129 31e31b8a bellard
    TYPE_ULONGLONG,
130 31e31b8a bellard
    TYPE_PTR,
131 31e31b8a bellard
    TYPE_ARRAY,
132 31e31b8a bellard
    TYPE_STRUCT,
133 31e31b8a bellard
} argtype;
134 31e31b8a bellard
135 31e31b8a bellard
#define MK_PTR(type) TYPE_PTR, type
136 31e31b8a bellard
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
137 31e31b8a bellard
#define MK_STRUCT(id) TYPE_STRUCT, id
138 31e31b8a bellard
139 31e31b8a bellard
#define THUNK_TARGET 0
140 31e31b8a bellard
#define THUNK_HOST   1
141 31e31b8a bellard
142 31e31b8a bellard
typedef struct {
143 31e31b8a bellard
    /* standard struct handling */
144 31e31b8a bellard
    const argtype *field_types;
145 31e31b8a bellard
    int nb_fields;
146 31e31b8a bellard
    int *field_offsets[2];
147 31e31b8a bellard
    /* special handling */
148 31e31b8a bellard
    void (*convert[2])(void *dst, const void *src);
149 31e31b8a bellard
    int size[2];
150 31e31b8a bellard
    int align[2];
151 31e31b8a bellard
    const char *name;
152 31e31b8a bellard
} StructEntry;
153 31e31b8a bellard
154 31e31b8a bellard
/* Translation table for bitmasks... */
155 31e31b8a bellard
typedef struct bitmask_transtbl {
156 31e31b8a bellard
        unsigned int        x86_mask;
157 31e31b8a bellard
        unsigned int        x86_bits;
158 31e31b8a bellard
        unsigned int        alpha_mask;
159 31e31b8a bellard
        unsigned int        alpha_bits;
160 31e31b8a bellard
} bitmask_transtbl;
161 31e31b8a bellard
162 31e31b8a bellard
void thunk_register_struct(int id, const char *name, const argtype *types);
163 31e31b8a bellard
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
164 31e31b8a bellard
const argtype *thunk_convert(void *dst, const void *src, 
165 31e31b8a bellard
                             const argtype *type_ptr, int to_host);
166 0ad041d4 bellard
#ifndef NO_THUNK_TYPE_SIZE
167 31e31b8a bellard
168 24374901 bellard
extern StructEntry struct_entries[];
169 24374901 bellard
170 24374901 bellard
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
171 24374901 bellard
{
172 24374901 bellard
    int type, size;
173 24374901 bellard
    const StructEntry *se;
174 24374901 bellard
175 24374901 bellard
    type = *type_ptr;
176 24374901 bellard
    switch(type) {
177 24374901 bellard
    case TYPE_CHAR:
178 24374901 bellard
        return 1;
179 24374901 bellard
    case TYPE_SHORT:
180 24374901 bellard
        return 2;
181 24374901 bellard
    case TYPE_INT:
182 24374901 bellard
        return 4;
183 24374901 bellard
    case TYPE_LONGLONG:
184 24374901 bellard
    case TYPE_ULONGLONG:
185 24374901 bellard
        return 8;
186 24374901 bellard
    case TYPE_LONG:
187 24374901 bellard
    case TYPE_ULONG:
188 24374901 bellard
    case TYPE_PTRVOID:
189 24374901 bellard
    case TYPE_PTR:
190 24374901 bellard
        if (is_host) {
191 24374901 bellard
            return HOST_LONG_SIZE;
192 24374901 bellard
        } else {
193 24374901 bellard
            return TARGET_LONG_SIZE;
194 24374901 bellard
        }
195 24374901 bellard
        break;
196 24374901 bellard
    case TYPE_ARRAY:
197 24374901 bellard
        size = type_ptr[1];
198 24374901 bellard
        return size * thunk_type_size(type_ptr + 2, is_host);
199 24374901 bellard
    case TYPE_STRUCT:
200 24374901 bellard
        se = struct_entries + type_ptr[1];
201 24374901 bellard
        return se->size[is_host];
202 24374901 bellard
    default:
203 24374901 bellard
        return -1;
204 24374901 bellard
    }
205 24374901 bellard
}
206 24374901 bellard
207 24374901 bellard
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
208 24374901 bellard
{
209 24374901 bellard
    int type;
210 24374901 bellard
    const StructEntry *se;
211 24374901 bellard
212 24374901 bellard
    type = *type_ptr;
213 24374901 bellard
    switch(type) {
214 24374901 bellard
    case TYPE_CHAR:
215 24374901 bellard
        return 1;
216 24374901 bellard
    case TYPE_SHORT:
217 24374901 bellard
        return 2;
218 24374901 bellard
    case TYPE_INT:
219 24374901 bellard
        return 4;
220 24374901 bellard
    case TYPE_LONGLONG:
221 24374901 bellard
    case TYPE_ULONGLONG:
222 24374901 bellard
        return 8;
223 24374901 bellard
    case TYPE_LONG:
224 24374901 bellard
    case TYPE_ULONG:
225 24374901 bellard
    case TYPE_PTRVOID:
226 24374901 bellard
    case TYPE_PTR:
227 24374901 bellard
        if (is_host) {
228 24374901 bellard
            return HOST_LONG_SIZE;
229 24374901 bellard
        } else {
230 24374901 bellard
            return TARGET_LONG_SIZE;
231 24374901 bellard
        }
232 24374901 bellard
        break;
233 24374901 bellard
    case TYPE_ARRAY:
234 24374901 bellard
        return thunk_type_align(type_ptr + 2, is_host);
235 24374901 bellard
    case TYPE_STRUCT:
236 24374901 bellard
        se = struct_entries + type_ptr[1];
237 24374901 bellard
        return se->align[is_host];
238 24374901 bellard
    default:
239 24374901 bellard
        return -1;
240 24374901 bellard
    }
241 24374901 bellard
}
242 24374901 bellard
243 0ad041d4 bellard
#endif /* NO_THUNK_TYPE_SIZE */
244 0ad041d4 bellard
245 31e31b8a bellard
unsigned int target_to_host_bitmask(unsigned int x86_mask, 
246 31e31b8a bellard
                                    bitmask_transtbl * trans_tbl);
247 31e31b8a bellard
unsigned int host_to_target_bitmask(unsigned int alpha_mask, 
248 31e31b8a bellard
                                    bitmask_transtbl * trans_tbl);
249 31e31b8a bellard
250 31e31b8a bellard
#endif