Statistics
| Branch: | Revision:

root / thunk.h @ 3ef693a0

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
#ifdef HAVE_BYTESWAP_H
27
#include <byteswap.h>
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
({ \
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) )); \
60
})
61

    
62
#endif
63

    
64
#ifdef WORDS_BIGENDIAN
65
#define BSWAP_NEEDED
66
#endif
67

    
68
/* XXX: autoconf */
69
#define TARGET_I386
70
#define TARGET_LONG_BITS 32
71

    
72

    
73
#if defined(__alpha__)
74
#define HOST_LONG_BITS 64
75
#else
76
#define HOST_LONG_BITS 32
77
#endif
78

    
79
#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
80
#define HOST_LONG_SIZE (TARGET_LONG_BITS / 8)
81

    
82
static inline uint16_t bswap16(uint16_t x)
83
{
84
    return bswap_16(x);
85
}
86

    
87
static inline uint32_t bswap32(uint32_t x) 
88
{
89
    return bswap_32(x);
90
}
91

    
92
static inline uint64_t bswap64(uint64_t x) 
93
{
94
    return bswap_64(x);
95
}
96

    
97
static void inline bswap16s(uint16_t *s)
98
{
99
    *s = bswap16(*s);
100
}
101

    
102
static void inline bswap32s(uint32_t *s)
103
{
104
    *s = bswap32(*s);
105
}
106

    
107
static void inline bswap64s(uint64_t *s)
108
{
109
    *s = bswap64(*s);
110
}
111

    
112
#ifdef BSWAP_NEEDED
113

    
114
static inline uint16_t tswap16(uint16_t s)
115
{
116
    return bswap16(s);
117
}
118

    
119
static inline uint32_t tswap32(uint32_t s)
120
{
121
    return bswap32(s);
122
}
123

    
124
static inline uint64_t tswap64(uint64_t s)
125
{
126
    return bswap64(s);
127
}
128

    
129
static void inline tswap16s(uint16_t *s)
130
{
131
    *s = bswap16(*s);
132
}
133

    
134
static void inline tswap32s(uint32_t *s)
135
{
136
    *s = bswap32(*s);
137
}
138

    
139
static void inline tswap64s(uint64_t *s)
140
{
141
    *s = bswap64(*s);
142
}
143

    
144
#else
145

    
146
static inline uint16_t tswap16(uint16_t s)
147
{
148
    return s;
149
}
150

    
151
static inline uint32_t tswap32(uint32_t s)
152
{
153
    return s;
154
}
155

    
156
static inline uint64_t tswap64(uint64_t s)
157
{
158
    return s;
159
}
160

    
161
static void inline tswap16s(uint16_t *s)
162
{
163
}
164

    
165
static void inline tswap32s(uint32_t *s)
166
{
167
}
168

    
169
static void inline tswap64s(uint64_t *s)
170
{
171
}
172

    
173
#endif
174

    
175
#if TARGET_LONG_SIZE == 4
176
#define tswapl(s) tswap32(s)
177
#define tswapls(s) tswap32s((uint32_t *)(s))
178
#else
179
#define tswapl(s) tswap64(s)
180
#define tswapls(s) tswap64s((uint64_t *)(s))
181
#endif
182

    
183
#if TARGET_LONG_SIZE == 4
184
typedef int32_t target_long;
185
typedef uint32_t target_ulong;
186
#elif TARGET_LONG_SIZE == 8
187
typedef int64_t target_long;
188
typedef uint64_t target_ulong;
189
#else
190
#error TARGET_LONG_SIZE undefined
191
#endif
192

    
193
/* types enums definitions */
194

    
195
typedef enum argtype {
196
    TYPE_NULL,
197
    TYPE_CHAR,
198
    TYPE_SHORT,
199
    TYPE_INT,
200
    TYPE_LONG,
201
    TYPE_ULONG,
202
    TYPE_PTRVOID, /* pointer on unknown data */
203
    TYPE_LONGLONG,
204
    TYPE_ULONGLONG,
205
    TYPE_PTR,
206
    TYPE_ARRAY,
207
    TYPE_STRUCT,
208
} argtype;
209

    
210
#define MK_PTR(type) TYPE_PTR, type
211
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
212
#define MK_STRUCT(id) TYPE_STRUCT, id
213

    
214
#define THUNK_TARGET 0
215
#define THUNK_HOST   1
216

    
217
typedef struct {
218
    /* standard struct handling */
219
    const argtype *field_types;
220
    int nb_fields;
221
    int *field_offsets[2];
222
    /* special handling */
223
    void (*convert[2])(void *dst, const void *src);
224
    int size[2];
225
    int align[2];
226
    const char *name;
227
} StructEntry;
228

    
229
/* Translation table for bitmasks... */
230
typedef struct bitmask_transtbl {
231
        unsigned int        x86_mask;
232
        unsigned int        x86_bits;
233
        unsigned int        alpha_mask;
234
        unsigned int        alpha_bits;
235
} bitmask_transtbl;
236

    
237
void thunk_register_struct(int id, const char *name, const argtype *types);
238
void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
239
const argtype *thunk_convert(void *dst, const void *src, 
240
                             const argtype *type_ptr, int to_host);
241

    
242
unsigned int target_to_host_bitmask(unsigned int x86_mask, 
243
                                    bitmask_transtbl * trans_tbl);
244
unsigned int host_to_target_bitmask(unsigned int alpha_mask, 
245
                                    bitmask_transtbl * trans_tbl);
246

    
247
#endif