Statistics
| Branch: | Revision:

root / def-helper.h @ 57d585f7

History | View | Annotate | Download (8.1 kB)

1
/* Helper file for declaring TCG helper functions.
2
   Should be included at the start and end of target-foo/helper.h.
3

4
   Targets should use DEF_HELPER_N and DEF_HELPER_FLAGS_N to declare helper
5
   functions.  Names should be specified without the helper_ prefix, and
6
   the return and argument types specified.  3 basic types are understood
7
   (i32, i64 and ptr).  Additional aliases are provided for convenience and
8
   to match the types used by the C helper implementation.
9

10
   The target helper.h should be included in all files that use/define
11
   helper functions.  THis will ensure that function prototypes are
12
   consistent.  In addition it should be included an extra two times for
13
   helper.c, defining:
14
    GEN_HELPER 1 to produce op generation functions (gen_helper_*)
15
    GEN_HELPER 2 to do runtime registration helper functions.
16
 */
17

    
18
#ifndef DEF_HELPER_H
19
#define DEF_HELPER_H 1
20

    
21
#define HELPER(name) glue(helper_, name)
22

    
23
#define GET_TCGV_i32 GET_TCGV_I32
24
#define GET_TCGV_i64 GET_TCGV_I64
25
#define GET_TCGV_ptr GET_TCGV_PTR
26

    
27
/* Some types that make sense in C, but not for TCG.  */
28
#define dh_alias_i32 i32
29
#define dh_alias_s32 i32
30
#define dh_alias_int i32
31
#define dh_alias_i64 i64
32
#define dh_alias_s64 i64
33
#define dh_alias_f32 i32
34
#define dh_alias_f64 i64
35
#if TARGET_LONG_BITS == 32
36
#define dh_alias_tl i32
37
#else
38
#define dh_alias_tl i64
39
#endif
40
#define dh_alias_ptr ptr
41
#define dh_alias_void void
42
#define dh_alias_env ptr
43
#define dh_alias(t) glue(dh_alias_, t)
44

    
45
#define dh_ctype_i32 uint32_t
46
#define dh_ctype_s32 int32_t
47
#define dh_ctype_int int
48
#define dh_ctype_i64 uint64_t
49
#define dh_ctype_s64 int64_t
50
#define dh_ctype_f32 float32
51
#define dh_ctype_f64 float64
52
#define dh_ctype_tl target_ulong
53
#define dh_ctype_ptr void *
54
#define dh_ctype_void void
55
#define dh_ctype_env CPUArchState *
56
#define dh_ctype(t) dh_ctype_##t
57

    
58
/* We can't use glue() here because it falls foul of C preprocessor
59
   recursive expansion rules.  */
60
#define dh_retvar_decl0_void void
61
#define dh_retvar_decl0_i32 TCGv_i32 retval
62
#define dh_retvar_decl0_i64 TCGv_i64 retval
63
#define dh_retvar_decl0_ptr TCGv_ptr retval
64
#define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
65

    
66
#define dh_retvar_decl_void
67
#define dh_retvar_decl_i32 TCGv_i32 retval,
68
#define dh_retvar_decl_i64 TCGv_i64 retval,
69
#define dh_retvar_decl_ptr TCGv_ptr retval,
70
#define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
71

    
72
#define dh_retvar_void TCG_CALL_DUMMY_ARG
73
#define dh_retvar_i32 GET_TCGV_i32(retval)
74
#define dh_retvar_i64 GET_TCGV_i64(retval)
75
#define dh_retvar_ptr GET_TCGV_ptr(retval)
76
#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
77

    
78
#define dh_is_64bit_void 0
79
#define dh_is_64bit_i32 0
80
#define dh_is_64bit_i64 1
81
#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
82
#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
83

    
84
#define dh_is_signed_void 0
85
#define dh_is_signed_i32 0
86
#define dh_is_signed_s32 1
87
#define dh_is_signed_i64 0
88
#define dh_is_signed_s64 1
89
#define dh_is_signed_f32 0
90
#define dh_is_signed_f64 0
91
#define dh_is_signed_tl  0
92
#define dh_is_signed_int 1
93
/* ??? This is highly specific to the host cpu.  There are even special
94
   extension instructions that may be required, e.g. ia64's addp4.  But
95
   for now we don't support any 64-bit targets with 32-bit pointers.  */
96
#define dh_is_signed_ptr 0
97
#define dh_is_signed_env dh_is_signed_ptr
98
#define dh_is_signed(t) dh_is_signed_##t
99

    
100
#define dh_sizemask(t, n) \
101
  sizemask |= dh_is_64bit(t) << (n*2); \
102
  sizemask |= dh_is_signed(t) << (n*2+1)
103

    
104
#define dh_arg(t, n) \
105
  args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
106
  dh_sizemask(t, n)
107

    
108
#define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
109

    
110

    
111
#define DEF_HELPER_0(name, ret) \
112
    DEF_HELPER_FLAGS_0(name, 0, ret)
113
#define DEF_HELPER_1(name, ret, t1) \
114
    DEF_HELPER_FLAGS_1(name, 0, ret, t1)
115
#define DEF_HELPER_2(name, ret, t1, t2) \
116
    DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2)
117
#define DEF_HELPER_3(name, ret, t1, t2, t3) \
118
    DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
119
#define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
120
    DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
121
#define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
122
    DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
123

    
124
#endif /* DEF_HELPER_H */
125

    
126
#ifndef GEN_HELPER
127
/* Function prototypes.  */
128

    
129
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
130
dh_ctype(ret) HELPER(name) (void);
131

    
132
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
133
dh_ctype(ret) HELPER(name) (dh_ctype(t1));
134

    
135
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
136
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
137

    
138
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
139
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
140

    
141
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
142
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
143
                                   dh_ctype(t4));
144

    
145
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
146
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
147
                            dh_ctype(t4), dh_ctype(t5));
148

    
149
#undef GEN_HELPER
150
#define GEN_HELPER -1
151

    
152
#elif GEN_HELPER == 1
153
/* Gen functions.  */
154

    
155
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
156
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
157
{ \
158
  int sizemask; \
159
  sizemask = dh_is_64bit(ret); \
160
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \
161
}
162

    
163
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
164
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
165
{ \
166
  TCGArg args[1]; \
167
  int sizemask = 0; \
168
  dh_sizemask(ret, 0); \
169
  dh_arg(t1, 1); \
170
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
171
}
172

    
173
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
174
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
175
    dh_arg_decl(t2, 2)) \
176
{ \
177
  TCGArg args[2]; \
178
  int sizemask = 0; \
179
  dh_sizemask(ret, 0); \
180
  dh_arg(t1, 1); \
181
  dh_arg(t2, 2); \
182
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
183
}
184

    
185
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
186
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
187
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
188
{ \
189
  TCGArg args[3]; \
190
  int sizemask = 0; \
191
  dh_sizemask(ret, 0); \
192
  dh_arg(t1, 1); \
193
  dh_arg(t2, 2); \
194
  dh_arg(t3, 3); \
195
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
196
}
197

    
198
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
199
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
200
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
201
{ \
202
  TCGArg args[4]; \
203
  int sizemask = 0; \
204
  dh_sizemask(ret, 0); \
205
  dh_arg(t1, 1); \
206
  dh_arg(t2, 2); \
207
  dh_arg(t3, 3); \
208
  dh_arg(t4, 4); \
209
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
210
}
211

    
212
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
213
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
214
    dh_arg_decl(t1, 1),  dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
215
    dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
216
{ \
217
  TCGArg args[5]; \
218
  int sizemask = 0; \
219
  dh_sizemask(ret, 0); \
220
  dh_arg(t1, 1); \
221
  dh_arg(t2, 2); \
222
  dh_arg(t3, 3); \
223
  dh_arg(t4, 4); \
224
  dh_arg(t5, 5); \
225
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 5, args); \
226
}
227

    
228
#undef GEN_HELPER
229
#define GEN_HELPER -1
230

    
231
#elif GEN_HELPER == 2
232
/* Register helpers.  */
233

    
234
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
235
tcg_register_helper(HELPER(name), #name);
236

    
237
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
238
DEF_HELPER_FLAGS_0(name, flags, ret)
239

    
240
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
241
DEF_HELPER_FLAGS_0(name, flags, ret)
242

    
243
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
244
DEF_HELPER_FLAGS_0(name, flags, ret)
245

    
246
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
247
DEF_HELPER_FLAGS_0(name, flags, ret)
248

    
249
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
250
DEF_HELPER_FLAGS_0(name, flags, ret)
251

    
252
#undef GEN_HELPER
253
#define GEN_HELPER -1
254

    
255
#elif GEN_HELPER == -1
256
/* Undefine macros.  */
257

    
258
#undef DEF_HELPER_FLAGS_0
259
#undef DEF_HELPER_FLAGS_1
260
#undef DEF_HELPER_FLAGS_2
261
#undef DEF_HELPER_FLAGS_3
262
#undef DEF_HELPER_FLAGS_4
263
#undef DEF_HELPER_FLAGS_5
264
#undef GEN_HELPER
265

    
266
#endif