|
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 "cpu.h" |
|
25 |
|
26 /* types enums definitions */ |
|
27 |
|
28 typedef enum argtype { |
|
29 TYPE_NULL, |
|
30 TYPE_CHAR, |
|
31 TYPE_SHORT, |
|
32 TYPE_INT, |
|
33 TYPE_LONG, |
|
34 TYPE_ULONG, |
|
35 TYPE_PTRVOID, /* pointer on unknown data */ |
|
36 TYPE_LONGLONG, |
|
37 TYPE_ULONGLONG, |
|
38 TYPE_PTR, |
|
39 TYPE_ARRAY, |
|
40 TYPE_STRUCT, |
|
41 } argtype; |
|
42 |
|
43 #define MK_PTR(type) TYPE_PTR, type |
|
44 #define MK_ARRAY(type, size) TYPE_ARRAY, size, type |
|
45 #define MK_STRUCT(id) TYPE_STRUCT, id |
|
46 |
|
47 #define THUNK_TARGET 0 |
|
48 #define THUNK_HOST 1 |
|
49 |
|
50 typedef struct { |
|
51 /* standard struct handling */ |
|
52 const argtype *field_types; |
|
53 int nb_fields; |
|
54 int *field_offsets[2]; |
|
55 /* special handling */ |
|
56 void (*convert[2])(void *dst, const void *src); |
|
57 int size[2]; |
|
58 int align[2]; |
|
59 const char *name; |
|
60 } StructEntry; |
|
61 |
|
62 /* Translation table for bitmasks... */ |
|
63 typedef struct bitmask_transtbl { |
|
64 unsigned int x86_mask; |
|
65 unsigned int x86_bits; |
|
66 unsigned int alpha_mask; |
|
67 unsigned int alpha_bits; |
|
68 } bitmask_transtbl; |
|
69 |
|
70 void thunk_register_struct(int id, const char *name, const argtype *types); |
|
71 void thunk_register_struct_direct(int id, const char *name, |
|
72 const StructEntry *se1); |
|
73 const argtype *thunk_convert(void *dst, const void *src, |
|
74 const argtype *type_ptr, int to_host); |
|
75 #ifndef NO_THUNK_TYPE_SIZE |
|
76 |
|
77 extern StructEntry struct_entries[]; |
|
78 |
|
79 int thunk_type_size_array(const argtype *type_ptr, int is_host); |
|
80 int thunk_type_align_array(const argtype *type_ptr, int is_host); |
|
81 |
|
82 static inline int thunk_type_size(const argtype *type_ptr, int is_host) |
|
83 { |
|
84 int type, size; |
|
85 const StructEntry *se; |
|
86 |
|
87 type = *type_ptr; |
|
88 switch(type) { |
|
89 case TYPE_CHAR: |
|
90 return 1; |
|
91 case TYPE_SHORT: |
|
92 return 2; |
|
93 case TYPE_INT: |
|
94 return 4; |
|
95 case TYPE_LONGLONG: |
|
96 case TYPE_ULONGLONG: |
|
97 return 8; |
|
98 case TYPE_LONG: |
|
99 case TYPE_ULONG: |
|
100 case TYPE_PTRVOID: |
|
101 case TYPE_PTR: |
|
102 if (is_host) { |
|
103 return HOST_LONG_SIZE; |
|
104 } else { |
|
105 return TARGET_ABI_BITS / 8; |
|
106 } |
|
107 break; |
|
108 case TYPE_ARRAY: |
|
109 size = type_ptr[1]; |
|
110 return size * thunk_type_size_array(type_ptr + 2, is_host); |
|
111 case TYPE_STRUCT: |
|
112 se = struct_entries + type_ptr[1]; |
|
113 return se->size[is_host]; |
|
114 default: |
|
115 return -1; |
|
116 } |
|
117 } |
|
118 |
|
119 static inline int thunk_type_align(const argtype *type_ptr, int is_host) |
|
120 { |
|
121 int type; |
|
122 const StructEntry *se; |
|
123 |
|
124 type = *type_ptr; |
|
125 switch(type) { |
|
126 case TYPE_CHAR: |
|
127 return 1; |
|
128 case TYPE_SHORT: |
|
129 return 2; |
|
130 case TYPE_INT: |
|
131 return 4; |
|
132 case TYPE_LONGLONG: |
|
133 case TYPE_ULONGLONG: |
|
134 return 8; |
|
135 case TYPE_LONG: |
|
136 case TYPE_ULONG: |
|
137 case TYPE_PTRVOID: |
|
138 case TYPE_PTR: |
|
139 if (is_host) { |
|
140 return HOST_LONG_SIZE; |
|
141 } else { |
|
142 return TARGET_ABI_BITS / 8; |
|
143 } |
|
144 break; |
|
145 case TYPE_ARRAY: |
|
146 return thunk_type_align_array(type_ptr + 2, is_host); |
|
147 case TYPE_STRUCT: |
|
148 se = struct_entries + type_ptr[1]; |
|
149 return se->align[is_host]; |
|
150 default: |
|
151 return -1; |
|
152 } |
|
153 } |
|
154 |
|
155 #endif /* NO_THUNK_TYPE_SIZE */ |
|
156 |
|
157 unsigned int target_to_host_bitmask(unsigned int x86_mask, |
|
158 const bitmask_transtbl * trans_tbl); |
|
159 unsigned int host_to_target_bitmask(unsigned int alpha_mask, |
|
160 const bitmask_transtbl * trans_tbl); |
|
161 |
|
162 #endif |