Statistics
| Branch: | Revision:

root / thunk.h @ a74cdab4

History | View | Annotate | Download (4.1 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, see <http://www.gnu.org/licenses/>.
18
 */
19
#ifndef THUNK_H
20
#define THUNK_H
21

    
22
#include <inttypes.h>
23
#include "cpu.h"
24

    
25
/* types enums definitions */
26

    
27
typedef enum argtype {
28
    TYPE_NULL,
29
    TYPE_CHAR,
30
    TYPE_SHORT,
31
    TYPE_INT,
32
    TYPE_LONG,
33
    TYPE_ULONG,
34
    TYPE_PTRVOID, /* pointer on unknown data */
35
    TYPE_LONGLONG,
36
    TYPE_ULONGLONG,
37
    TYPE_PTR,
38
    TYPE_ARRAY,
39
    TYPE_STRUCT,
40
} argtype;
41

    
42
#define MK_PTR(type) TYPE_PTR, type
43
#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
44
#define MK_STRUCT(id) TYPE_STRUCT, id
45

    
46
#define THUNK_TARGET 0
47
#define THUNK_HOST   1
48

    
49
typedef struct {
50
    /* standard struct handling */
51
    const argtype *field_types;
52
    int nb_fields;
53
    int *field_offsets[2];
54
    /* special handling */
55
    void (*convert[2])(void *dst, const void *src);
56
    int size[2];
57
    int align[2];
58
    const char *name;
59
} StructEntry;
60

    
61
/* Translation table for bitmasks... */
62
typedef struct bitmask_transtbl {
63
        unsigned int        x86_mask;
64
        unsigned int        x86_bits;
65
        unsigned int        alpha_mask;
66
        unsigned int        alpha_bits;
67
} bitmask_transtbl;
68

    
69
void thunk_register_struct(int id, const char *name, const argtype *types);
70
void thunk_register_struct_direct(int id, const char *name,
71
                                  const StructEntry *se1);
72
const argtype *thunk_convert(void *dst, const void *src,
73
                             const argtype *type_ptr, int to_host);
74
#ifndef NO_THUNK_TYPE_SIZE
75

    
76
extern StructEntry struct_entries[];
77

    
78
int thunk_type_size_array(const argtype *type_ptr, int is_host);
79
int thunk_type_align_array(const argtype *type_ptr, int is_host);
80

    
81
static inline int thunk_type_size(const argtype *type_ptr, int is_host)
82
{
83
    int type, size;
84
    const StructEntry *se;
85

    
86
    type = *type_ptr;
87
    switch(type) {
88
    case TYPE_CHAR:
89
        return 1;
90
    case TYPE_SHORT:
91
        return 2;
92
    case TYPE_INT:
93
        return 4;
94
    case TYPE_LONGLONG:
95
    case TYPE_ULONGLONG:
96
        return 8;
97
    case TYPE_LONG:
98
    case TYPE_ULONG:
99
    case TYPE_PTRVOID:
100
    case TYPE_PTR:
101
        if (is_host) {
102
            return HOST_LONG_SIZE;
103
        } else {
104
            return TARGET_ABI_BITS / 8;
105
        }
106
        break;
107
    case TYPE_ARRAY:
108
        size = type_ptr[1];
109
        return size * thunk_type_size_array(type_ptr + 2, is_host);
110
    case TYPE_STRUCT:
111
        se = struct_entries + type_ptr[1];
112
        return se->size[is_host];
113
    default:
114
        return -1;
115
    }
116
}
117

    
118
static inline int thunk_type_align(const argtype *type_ptr, int is_host)
119
{
120
    int type;
121
    const StructEntry *se;
122

    
123
    type = *type_ptr;
124
    switch(type) {
125
    case TYPE_CHAR:
126
        return 1;
127
    case TYPE_SHORT:
128
        return 2;
129
    case TYPE_INT:
130
        return 4;
131
    case TYPE_LONGLONG:
132
    case TYPE_ULONGLONG:
133
        return 8;
134
    case TYPE_LONG:
135
    case TYPE_ULONG:
136
    case TYPE_PTRVOID:
137
    case TYPE_PTR:
138
        if (is_host) {
139
            return HOST_LONG_SIZE;
140
        } else {
141
            return TARGET_ABI_BITS / 8;
142
        }
143
        break;
144
    case TYPE_ARRAY:
145
        return thunk_type_align_array(type_ptr + 2, is_host);
146
    case TYPE_STRUCT:
147
        se = struct_entries + type_ptr[1];
148
        return se->align[is_host];
149
    default:
150
        return -1;
151
    }
152
}
153

    
154
#endif /* NO_THUNK_TYPE_SIZE */
155

    
156
unsigned int target_to_host_bitmask(unsigned int x86_mask,
157
                                    const bitmask_transtbl * trans_tbl);
158
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
159
                                    const bitmask_transtbl * trans_tbl);
160

    
161
#endif