root / def-helper.h @ a22f123c
History | View | Annotate | Download (7.2 kB)
1 | a7812ae4 | pbrook | /* Helper file for declaring TCG helper functions.
|
---|---|---|---|
2 | a7812ae4 | pbrook | Should be included at the start and end of target-foo/helper.h.
|
3 | a7812ae4 | pbrook | |
4 | a7812ae4 | pbrook | Targets should use DEF_HELPER_N and DEF_HELPER_FLAGS_N to declare helper
|
5 | a7812ae4 | pbrook | functions. Names should be specified without the helper_ prefix, and
|
6 | a7812ae4 | pbrook | the return and argument types specified. 3 basic types are understood
|
7 | a7812ae4 | pbrook | (i32, i64 and ptr). Additional aliases are provided for convenience and
|
8 | a7812ae4 | pbrook | to match the types used by the C helper implementation.
|
9 | a7812ae4 | pbrook | |
10 | a7812ae4 | pbrook | The target helper.h should be included in all files that use/define
|
11 | a7812ae4 | pbrook | helper functions. THis will ensure that function prototypes are
|
12 | a7812ae4 | pbrook | consistent. In addition it should be included an extra two times for
|
13 | a7812ae4 | pbrook | helper.c, defining:
|
14 | a7812ae4 | pbrook | GEN_HELPER 1 to produce op generation functions (gen_helper_*)
|
15 | a7812ae4 | pbrook | GEN_HELPER 2 to do runtime registration helper functions.
|
16 | a7812ae4 | pbrook | */
|
17 | a7812ae4 | pbrook | |
18 | a7812ae4 | pbrook | #ifndef DEF_HELPER_H
|
19 | a7812ae4 | pbrook | #define DEF_HELPER_H 1 |
20 | a7812ae4 | pbrook | |
21 | a7812ae4 | pbrook | #define HELPER(name) glue(helper_, name)
|
22 | a7812ae4 | pbrook | |
23 | a7812ae4 | pbrook | #define GET_TCGV_i32 GET_TCGV_I32
|
24 | a7812ae4 | pbrook | #define GET_TCGV_i64 GET_TCGV_I64
|
25 | a7812ae4 | pbrook | #define GET_TCGV_ptr GET_TCGV_PTR
|
26 | a7812ae4 | pbrook | |
27 | a7812ae4 | pbrook | /* Some types that make sense in C, but not for TCG. */
|
28 | a7812ae4 | pbrook | #define dh_alias_i32 i32
|
29 | a7812ae4 | pbrook | #define dh_alias_s32 i32
|
30 | a7812ae4 | pbrook | #define dh_alias_int i32
|
31 | a7812ae4 | pbrook | #define dh_alias_i64 i64
|
32 | a7812ae4 | pbrook | #define dh_alias_s64 i64
|
33 | a7812ae4 | pbrook | #define dh_alias_f32 i32
|
34 | a7812ae4 | pbrook | #define dh_alias_f64 i64
|
35 | a7812ae4 | pbrook | #if TARGET_LONG_BITS == 32 |
36 | a7812ae4 | pbrook | #define dh_alias_tl i32
|
37 | a7812ae4 | pbrook | #else
|
38 | a7812ae4 | pbrook | #define dh_alias_tl i64
|
39 | a7812ae4 | pbrook | #endif
|
40 | a7812ae4 | pbrook | #define dh_alias_ptr ptr
|
41 | a7812ae4 | pbrook | #define dh_alias_void void |
42 | a7812ae4 | pbrook | #define dh_alias_env ptr
|
43 | a7812ae4 | pbrook | #define dh_alias(t) glue(dh_alias_, t)
|
44 | a7812ae4 | pbrook | |
45 | a7812ae4 | pbrook | #define dh_ctype_i32 uint32_t
|
46 | a7812ae4 | pbrook | #define dh_ctype_s32 int32_t
|
47 | a7812ae4 | pbrook | #define dh_ctype_int int |
48 | a7812ae4 | pbrook | #define dh_ctype_i64 uint64_t
|
49 | a7812ae4 | pbrook | #define dh_ctype_s64 int64_t
|
50 | a7812ae4 | pbrook | #define dh_ctype_f32 float32
|
51 | a7812ae4 | pbrook | #define dh_ctype_f64 float64
|
52 | a7812ae4 | pbrook | #define dh_ctype_tl target_ulong
|
53 | a7812ae4 | pbrook | #define dh_ctype_ptr void * |
54 | a7812ae4 | pbrook | #define dh_ctype_void void |
55 | a7812ae4 | pbrook | #define dh_ctype_env CPUState *
|
56 | a7812ae4 | pbrook | #define dh_ctype(t) dh_ctype_##t |
57 | a7812ae4 | pbrook | |
58 | a7812ae4 | pbrook | /* We can't use glue() here because it falls foul of C preprocessor
|
59 | a7812ae4 | pbrook | recursive expansion rules. */
|
60 | a7812ae4 | pbrook | #define dh_retvar_decl0_void void |
61 | a7812ae4 | pbrook | #define dh_retvar_decl0_i32 TCGv_i32 retval
|
62 | a7812ae4 | pbrook | #define dh_retvar_decl0_i64 TCGv_i64 retval
|
63 | 9c9c310a | Igor Kovalenko | #define dh_retvar_decl0_ptr TCGv_ptr retval
|
64 | a7812ae4 | pbrook | #define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
|
65 | a7812ae4 | pbrook | |
66 | a7812ae4 | pbrook | #define dh_retvar_decl_void
|
67 | a7812ae4 | pbrook | #define dh_retvar_decl_i32 TCGv_i32 retval,
|
68 | a7812ae4 | pbrook | #define dh_retvar_decl_i64 TCGv_i64 retval,
|
69 | 9c9c310a | Igor Kovalenko | #define dh_retvar_decl_ptr TCGv_ptr retval,
|
70 | a7812ae4 | pbrook | #define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
|
71 | a7812ae4 | pbrook | |
72 | a7812ae4 | pbrook | #define dh_retvar_void TCG_CALL_DUMMY_ARG
|
73 | a7812ae4 | pbrook | #define dh_retvar_i32 GET_TCGV_i32(retval)
|
74 | a7812ae4 | pbrook | #define dh_retvar_i64 GET_TCGV_i64(retval)
|
75 | a7812ae4 | pbrook | #define dh_retvar_ptr GET_TCGV_ptr(retval)
|
76 | a7812ae4 | pbrook | #define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
|
77 | a7812ae4 | pbrook | |
78 | a7812ae4 | pbrook | #define dh_is_64bit_void 0 |
79 | a7812ae4 | pbrook | #define dh_is_64bit_i32 0 |
80 | a7812ae4 | pbrook | #define dh_is_64bit_i64 1 |
81 | a7812ae4 | pbrook | #define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64) |
82 | a7812ae4 | pbrook | #define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
|
83 | a7812ae4 | pbrook | |
84 | 2bece2c8 | Richard Henderson | #define dh_is_signed_void 0 |
85 | 2bece2c8 | Richard Henderson | #define dh_is_signed_i32 0 |
86 | 2bece2c8 | Richard Henderson | #define dh_is_signed_s32 1 |
87 | 2bece2c8 | Richard Henderson | #define dh_is_signed_i64 0 |
88 | 2bece2c8 | Richard Henderson | #define dh_is_signed_s64 1 |
89 | 2bece2c8 | Richard Henderson | #define dh_is_signed_f32 0 |
90 | 2bece2c8 | Richard Henderson | #define dh_is_signed_f64 0 |
91 | 2bece2c8 | Richard Henderson | #define dh_is_signed_tl 0 |
92 | 2bece2c8 | Richard Henderson | #define dh_is_signed_int 1 |
93 | 2bece2c8 | Richard Henderson | /* ??? This is highly specific to the host cpu. There are even special
|
94 | 2bece2c8 | Richard Henderson | extension instructions that may be required, e.g. ia64's addp4. But
|
95 | 2bece2c8 | Richard Henderson | for now we don't support any 64-bit targets with 32-bit pointers. */
|
96 | 2bece2c8 | Richard Henderson | #define dh_is_signed_ptr 0 |
97 | 2bece2c8 | Richard Henderson | #define dh_is_signed_env dh_is_signed_ptr
|
98 | 2bece2c8 | Richard Henderson | #define dh_is_signed(t) dh_is_signed_##t |
99 | 2bece2c8 | Richard Henderson | |
100 | 2bece2c8 | Richard Henderson | #define dh_sizemask(t, n) \
|
101 | 2bece2c8 | Richard Henderson | sizemask |= dh_is_64bit(t) << (n*2); \
|
102 | 2bece2c8 | Richard Henderson | sizemask |= dh_is_signed(t) << (n*2+1) |
103 | 2bece2c8 | Richard Henderson | |
104 | a7812ae4 | pbrook | #define dh_arg(t, n) \
|
105 | a7812ae4 | pbrook | args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
|
106 | 2bece2c8 | Richard Henderson | dh_sizemask(t, n) |
107 | a7812ae4 | pbrook | |
108 | a7812ae4 | pbrook | #define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
|
109 | a7812ae4 | pbrook | |
110 | a7812ae4 | pbrook | |
111 | a7812ae4 | pbrook | #define DEF_HELPER_0(name, ret) \
|
112 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_0(name, 0, ret)
|
113 | a7812ae4 | pbrook | #define DEF_HELPER_1(name, ret, t1) \
|
114 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_1(name, 0, ret, t1)
|
115 | a7812ae4 | pbrook | #define DEF_HELPER_2(name, ret, t1, t2) \
|
116 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2)
|
117 | a7812ae4 | pbrook | #define DEF_HELPER_3(name, ret, t1, t2, t3) \
|
118 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
|
119 | a7812ae4 | pbrook | #define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
|
120 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
|
121 | a7812ae4 | pbrook | |
122 | a7812ae4 | pbrook | #endif /* DEF_HELPER_H */ |
123 | a7812ae4 | pbrook | |
124 | a7812ae4 | pbrook | #ifndef GEN_HELPER
|
125 | a7812ae4 | pbrook | /* Function prototypes. */
|
126 | a7812ae4 | pbrook | |
127 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_0(name, flags, ret) \
|
128 | a7812ae4 | pbrook | dh_ctype(ret) HELPER(name) (void);
|
129 | a7812ae4 | pbrook | |
130 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
|
131 | a7812ae4 | pbrook | dh_ctype(ret) HELPER(name) (dh_ctype(t1)); |
132 | a7812ae4 | pbrook | |
133 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
|
134 | a7812ae4 | pbrook | dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)); |
135 | a7812ae4 | pbrook | |
136 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
|
137 | a7812ae4 | pbrook | dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)); |
138 | a7812ae4 | pbrook | |
139 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
|
140 | a7812ae4 | pbrook | dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ |
141 | a7812ae4 | pbrook | dh_ctype(t4)); |
142 | a7812ae4 | pbrook | |
143 | a7812ae4 | pbrook | #undef GEN_HELPER
|
144 | a7812ae4 | pbrook | #define GEN_HELPER -1 |
145 | a7812ae4 | pbrook | |
146 | a7812ae4 | pbrook | #elif GEN_HELPER == 1 |
147 | a7812ae4 | pbrook | /* Gen functions. */
|
148 | a7812ae4 | pbrook | |
149 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_0(name, flags, ret) \
|
150 | a7812ae4 | pbrook | static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \ |
151 | a7812ae4 | pbrook | { \ |
152 | a7812ae4 | pbrook | int sizemask; \
|
153 | a7812ae4 | pbrook | sizemask = dh_is_64bit(ret); \ |
154 | a7812ae4 | pbrook | tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \ |
155 | a7812ae4 | pbrook | } |
156 | a7812ae4 | pbrook | |
157 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
|
158 | a7812ae4 | pbrook | static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \ |
159 | a7812ae4 | pbrook | { \ |
160 | a7812ae4 | pbrook | TCGArg args[1]; \
|
161 | 2bece2c8 | Richard Henderson | int sizemask = 0; \ |
162 | 2bece2c8 | Richard Henderson | dh_sizemask(ret, 0); \
|
163 | a7812ae4 | pbrook | dh_arg(t1, 1); \
|
164 | a7812ae4 | pbrook | tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
|
165 | a7812ae4 | pbrook | } |
166 | a7812ae4 | pbrook | |
167 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
|
168 | a7812ae4 | pbrook | static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ |
169 | a7812ae4 | pbrook | dh_arg_decl(t2, 2)) \
|
170 | a7812ae4 | pbrook | { \ |
171 | a7812ae4 | pbrook | TCGArg args[2]; \
|
172 | 2bece2c8 | Richard Henderson | int sizemask = 0; \ |
173 | 2bece2c8 | Richard Henderson | dh_sizemask(ret, 0); \
|
174 | a7812ae4 | pbrook | dh_arg(t1, 1); \
|
175 | a7812ae4 | pbrook | dh_arg(t2, 2); \
|
176 | a7812ae4 | pbrook | tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
|
177 | a7812ae4 | pbrook | } |
178 | a7812ae4 | pbrook | |
179 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
|
180 | a7812ae4 | pbrook | static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ |
181 | a7812ae4 | pbrook | dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \ |
182 | a7812ae4 | pbrook | { \ |
183 | a7812ae4 | pbrook | TCGArg args[3]; \
|
184 | 2bece2c8 | Richard Henderson | int sizemask = 0; \ |
185 | 2bece2c8 | Richard Henderson | dh_sizemask(ret, 0); \
|
186 | a7812ae4 | pbrook | dh_arg(t1, 1); \
|
187 | a7812ae4 | pbrook | dh_arg(t2, 2); \
|
188 | a7812ae4 | pbrook | dh_arg(t3, 3); \
|
189 | a7812ae4 | pbrook | tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
|
190 | a7812ae4 | pbrook | } |
191 | a7812ae4 | pbrook | |
192 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
|
193 | a7812ae4 | pbrook | static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ |
194 | a7812ae4 | pbrook | dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \ |
195 | a7812ae4 | pbrook | { \ |
196 | a7812ae4 | pbrook | TCGArg args[4]; \
|
197 | 2bece2c8 | Richard Henderson | int sizemask = 0; \ |
198 | 2bece2c8 | Richard Henderson | dh_sizemask(ret, 0); \
|
199 | a7812ae4 | pbrook | dh_arg(t1, 1); \
|
200 | a7812ae4 | pbrook | dh_arg(t2, 2); \
|
201 | a7812ae4 | pbrook | dh_arg(t3, 3); \
|
202 | a7812ae4 | pbrook | dh_arg(t4, 4); \
|
203 | a7812ae4 | pbrook | tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
|
204 | a7812ae4 | pbrook | } |
205 | a7812ae4 | pbrook | |
206 | a7812ae4 | pbrook | #undef GEN_HELPER
|
207 | a7812ae4 | pbrook | #define GEN_HELPER -1 |
208 | a7812ae4 | pbrook | |
209 | a7812ae4 | pbrook | #elif GEN_HELPER == 2 |
210 | a7812ae4 | pbrook | /* Register helpers. */
|
211 | a7812ae4 | pbrook | |
212 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_0(name, flags, ret) \
|
213 | a7812ae4 | pbrook | tcg_register_helper(HELPER(name), #name);
|
214 | a7812ae4 | pbrook | |
215 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
|
216 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_0(name, flags, ret) |
217 | a7812ae4 | pbrook | |
218 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
|
219 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_0(name, flags, ret) |
220 | a7812ae4 | pbrook | |
221 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
|
222 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_0(name, flags, ret) |
223 | a7812ae4 | pbrook | |
224 | a7812ae4 | pbrook | #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
|
225 | a7812ae4 | pbrook | DEF_HELPER_FLAGS_0(name, flags, ret) |
226 | a7812ae4 | pbrook | |
227 | a7812ae4 | pbrook | #undef GEN_HELPER
|
228 | a7812ae4 | pbrook | #define GEN_HELPER -1 |
229 | a7812ae4 | pbrook | |
230 | a7812ae4 | pbrook | #elif GEN_HELPER == -1 |
231 | a7812ae4 | pbrook | /* Undefine macros. */
|
232 | a7812ae4 | pbrook | |
233 | a7812ae4 | pbrook | #undef DEF_HELPER_FLAGS_0
|
234 | a7812ae4 | pbrook | #undef DEF_HELPER_FLAGS_1
|
235 | a7812ae4 | pbrook | #undef DEF_HELPER_FLAGS_2
|
236 | a7812ae4 | pbrook | #undef DEF_HELPER_FLAGS_3
|
237 | a7812ae4 | pbrook | #undef DEF_HELPER_FLAGS_4
|
238 | a7812ae4 | pbrook | #undef GEN_HELPER
|
239 | a7812ae4 | pbrook | |
240 | a7812ae4 | pbrook | #endif |