Statistics
| Branch: | Revision:

root / thunk.h @ c92b2e84

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