Statistics
| Branch: | Revision:

root / thunk.h @ facc68be

History | View | Annotate | Download (5.4 kB)

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
#include "bswap.h"
27

    
28
#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
29
#define BSWAP_NEEDED
30
#endif
31

    
32
/* XXX: autoconf */
33
#define TARGET_LONG_BITS 32
34

    
35
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
36

    
37
#ifdef BSWAP_NEEDED
38

    
39
static inline uint16_t tswap16(uint16_t s)
40
{
41
    return bswap16(s);
42
}
43

    
44
static inline uint32_t tswap32(uint32_t s)
45
{
46
    return bswap32(s);
47
}
48

    
49
static inline uint64_t tswap64(uint64_t s)
50
{
51
    return bswap64(s);
52
}
53

    
54
static inline void tswap16s(uint16_t *s)
55
{
56
    *s = bswap16(*s);
57
}
58

    
59
static inline void tswap32s(uint32_t *s)
60
{
61
    *s = bswap32(*s);
62
}
63

    
64
static inline void tswap64s(uint64_t *s)
65
{
66
    *s = bswap64(*s);
67
}
68

    
69
#else
70

    
71
static inline uint16_t tswap16(uint16_t s)
72
{
73
    return s;
74
}
75

    
76
static inline uint32_t tswap32(uint32_t s)
77
{
78
    return s;
79
}
80

    
81
static inline uint64_t tswap64(uint64_t s)
82
{
83
    return s;
84
}
85

    
86
static inline void tswap16s(uint16_t *s)
87
{
88
}
89

    
90
static inline void tswap32s(uint32_t *s)
91
{
92
}
93

    
94
static inline void tswap64s(uint64_t *s)
95
{
96
}
97

    
98
#endif
99

    
100
#if TARGET_LONG_SIZE == 4
101
#define tswapl(s) tswap32(s)
102
#define tswapls(s) tswap32s((uint32_t *)(s))
103
#else
104
#define tswapl(s) tswap64(s)
105
#define tswapls(s) tswap64s((uint64_t *)(s))
106
#endif
107

    
108
#if TARGET_LONG_SIZE == 4
109
typedef int32_t target_long;
110
typedef uint32_t target_ulong;
111
#elif TARGET_LONG_SIZE == 8
112
typedef int64_t target_long;
113
typedef uint64_t target_ulong;
114
#else
115
#error TARGET_LONG_SIZE undefined
116
#endif
117

    
118
/* types enums definitions */
119

    
120
typedef enum argtype {
121
    TYPE_NULL,
122
    TYPE_CHAR,
123
    TYPE_SHORT,
124
    TYPE_INT,
125
    TYPE_LONG,
126
    TYPE_ULONG,
127
    TYPE_PTRVOID, /* pointer on unknown data */
128
    TYPE_LONGLONG,
129
    TYPE_ULONGLONG,
130
    TYPE_PTR,
131
    TYPE_ARRAY,
132
    TYPE_STRUCT,
133
} argtype;
134

    
135
#define MK_PTR(type) TYPE_PTR, type
136
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
137
#define MK_STRUCT(id) TYPE_STRUCT, id
138

    
139
#define THUNK_TARGET 0
140
#define THUNK_HOST   1
141

    
142
typedef struct {
143
    /* standard struct handling */
144
    const argtype *field_types;
145
    int nb_fields;
146
    int *field_offsets[2];
147
    /* special handling */
148
    void (*convert[2])(void *dst, const void *src);
149
    int size[2];
150
    int align[2];
151
    const char *name;
152
} StructEntry;
153

    
154
/* Translation table for bitmasks... */
155
typedef struct bitmask_transtbl {
156
        unsigned int        x86_mask;
157
        unsigned int        x86_bits;
158
        unsigned int        alpha_mask;
159
        unsigned int        alpha_bits;
160
} bitmask_transtbl;
161

    
162
void thunk_register_struct(int id, const char *name, const argtype *types);
163
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
164
const argtype *thunk_convert(void *dst, const void *src, 
165
                             const argtype *type_ptr, int to_host);
166
#ifndef NO_THUNK_TYPE_SIZE
167

    
168
extern StructEntry struct_entries[];
169

    
170
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
171
{
172
    int type, size;
173
    const StructEntry *se;
174

    
175
    type = *type_ptr;
176
    switch(type) {
177
    case TYPE_CHAR:
178
        return 1;
179
    case TYPE_SHORT:
180
        return 2;
181
    case TYPE_INT:
182
        return 4;
183
    case TYPE_LONGLONG:
184
    case TYPE_ULONGLONG:
185
        return 8;
186
    case TYPE_LONG:
187
    case TYPE_ULONG:
188
    case TYPE_PTRVOID:
189
    case TYPE_PTR:
190
        if (is_host) {
191
            return HOST_LONG_SIZE;
192
        } else {
193
            return TARGET_LONG_SIZE;
194
        }
195
        break;
196
    case TYPE_ARRAY:
197
        size = type_ptr[1];
198
        return size * thunk_type_size(type_ptr + 2, is_host);
199
    case TYPE_STRUCT:
200
        se = struct_entries + type_ptr[1];
201
        return se->size[is_host];
202
    default:
203
        return -1;
204
    }
205
}
206

    
207
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
208
{
209
    int type;
210
    const StructEntry *se;
211

    
212
    type = *type_ptr;
213
    switch(type) {
214
    case TYPE_CHAR:
215
        return 1;
216
    case TYPE_SHORT:
217
        return 2;
218
    case TYPE_INT:
219
        return 4;
220
    case TYPE_LONGLONG:
221
    case TYPE_ULONGLONG:
222
        return 8;
223
    case TYPE_LONG:
224
    case TYPE_ULONG:
225
    case TYPE_PTRVOID:
226
    case TYPE_PTR:
227
        if (is_host) {
228
            return HOST_LONG_SIZE;
229
        } else {
230
            return TARGET_LONG_SIZE;
231
        }
232
        break;
233
    case TYPE_ARRAY:
234
        return thunk_type_align(type_ptr + 2, is_host);
235
    case TYPE_STRUCT:
236
        se = struct_entries + type_ptr[1];
237
        return se->align[is_host];
238
    default:
239
        return -1;
240
    }
241
}
242

    
243
#endif /* NO_THUNK_TYPE_SIZE */
244

    
245
unsigned int target_to_host_bitmask(unsigned int x86_mask, 
246
                                    bitmask_transtbl * trans_tbl);
247
unsigned int host_to_target_bitmask(unsigned int alpha_mask, 
248
                                    bitmask_transtbl * trans_tbl);
249

    
250
#endif