Statistics
| Branch: | Revision:

root / def-helper.h @ 6f06f178

History | View | Annotate | Download (8.4 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_noreturn noreturn
43
#define dh_alias_env ptr
44
#define dh_alias(t) glue(dh_alias_, t)
45

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

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

    
69
#define dh_retvar_decl_void
70
#define dh_retvar_decl_noreturn
71
#define dh_retvar_decl_i32 TCGv_i32 retval,
72
#define dh_retvar_decl_i64 TCGv_i64 retval,
73
#define dh_retvar_decl_ptr TCGv_ptr retval,
74
#define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
75

    
76
#define dh_retvar_void TCG_CALL_DUMMY_ARG
77
#define dh_retvar_noreturn TCG_CALL_DUMMY_ARG
78
#define dh_retvar_i32 GET_TCGV_i32(retval)
79
#define dh_retvar_i64 GET_TCGV_i64(retval)
80
#define dh_retvar_ptr GET_TCGV_ptr(retval)
81
#define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
82

    
83
#define dh_is_64bit_void 0
84
#define dh_is_64bit_noreturn 0
85
#define dh_is_64bit_i32 0
86
#define dh_is_64bit_i64 1
87
#define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
88
#define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
89

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

    
107
#define dh_sizemask(t, n) \
108
  sizemask |= dh_is_64bit(t) << (n*2); \
109
  sizemask |= dh_is_signed(t) << (n*2+1)
110

    
111
#define dh_arg(t, n) \
112
  args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
113
  dh_sizemask(t, n)
114

    
115
#define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
116

    
117

    
118
#define DEF_HELPER_0(name, ret) \
119
    DEF_HELPER_FLAGS_0(name, 0, ret)
120
#define DEF_HELPER_1(name, ret, t1) \
121
    DEF_HELPER_FLAGS_1(name, 0, ret, t1)
122
#define DEF_HELPER_2(name, ret, t1, t2) \
123
    DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2)
124
#define DEF_HELPER_3(name, ret, t1, t2, t3) \
125
    DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
126
#define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
127
    DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
128
#define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
129
    DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
130

    
131
#endif /* DEF_HELPER_H */
132

    
133
#ifndef GEN_HELPER
134
/* Function prototypes.  */
135

    
136
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
137
dh_ctype(ret) HELPER(name) (void);
138

    
139
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
140
dh_ctype(ret) HELPER(name) (dh_ctype(t1));
141

    
142
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
143
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
144

    
145
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
146
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
147

    
148
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
149
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
150
                                   dh_ctype(t4));
151

    
152
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
153
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
154
                            dh_ctype(t4), dh_ctype(t5));
155

    
156
#undef GEN_HELPER
157
#define GEN_HELPER -1
158

    
159
#elif GEN_HELPER == 1
160
/* Gen functions.  */
161

    
162
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
163
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
164
{ \
165
  int sizemask; \
166
  sizemask = dh_is_64bit(ret); \
167
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \
168
}
169

    
170
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
171
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
172
{ \
173
  TCGArg args[1]; \
174
  int sizemask = 0; \
175
  dh_sizemask(ret, 0); \
176
  dh_arg(t1, 1); \
177
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
178
}
179

    
180
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
181
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
182
    dh_arg_decl(t2, 2)) \
183
{ \
184
  TCGArg args[2]; \
185
  int sizemask = 0; \
186
  dh_sizemask(ret, 0); \
187
  dh_arg(t1, 1); \
188
  dh_arg(t2, 2); \
189
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
190
}
191

    
192
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
193
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
194
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
195
{ \
196
  TCGArg args[3]; \
197
  int sizemask = 0; \
198
  dh_sizemask(ret, 0); \
199
  dh_arg(t1, 1); \
200
  dh_arg(t2, 2); \
201
  dh_arg(t3, 3); \
202
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
203
}
204

    
205
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
206
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
207
    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
208
{ \
209
  TCGArg args[4]; \
210
  int sizemask = 0; \
211
  dh_sizemask(ret, 0); \
212
  dh_arg(t1, 1); \
213
  dh_arg(t2, 2); \
214
  dh_arg(t3, 3); \
215
  dh_arg(t4, 4); \
216
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
217
}
218

    
219
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
220
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
221
    dh_arg_decl(t1, 1),  dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
222
    dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
223
{ \
224
  TCGArg args[5]; \
225
  int sizemask = 0; \
226
  dh_sizemask(ret, 0); \
227
  dh_arg(t1, 1); \
228
  dh_arg(t2, 2); \
229
  dh_arg(t3, 3); \
230
  dh_arg(t4, 4); \
231
  dh_arg(t5, 5); \
232
  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 5, args); \
233
}
234

    
235
#undef GEN_HELPER
236
#define GEN_HELPER -1
237

    
238
#elif GEN_HELPER == 2
239
/* Register helpers.  */
240

    
241
#define DEF_HELPER_FLAGS_0(name, flags, ret) \
242
tcg_register_helper(HELPER(name), #name);
243

    
244
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
245
DEF_HELPER_FLAGS_0(name, flags, ret)
246

    
247
#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
248
DEF_HELPER_FLAGS_0(name, flags, ret)
249

    
250
#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
251
DEF_HELPER_FLAGS_0(name, flags, ret)
252

    
253
#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
254
DEF_HELPER_FLAGS_0(name, flags, ret)
255

    
256
#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
257
DEF_HELPER_FLAGS_0(name, flags, ret)
258

    
259
#undef GEN_HELPER
260
#define GEN_HELPER -1
261

    
262
#elif GEN_HELPER == -1
263
/* Undefine macros.  */
264

    
265
#undef DEF_HELPER_FLAGS_0
266
#undef DEF_HELPER_FLAGS_1
267
#undef DEF_HELPER_FLAGS_2
268
#undef DEF_HELPER_FLAGS_3
269
#undef DEF_HELPER_FLAGS_4
270
#undef DEF_HELPER_FLAGS_5
271
#undef GEN_HELPER
272

    
273
#endif