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 CPUState * 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 122 #endif /* DEF_HELPER_H */ 123 124 #ifndef GEN_HELPER 125 /* Function prototypes. */ 126 127 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 128 dh_ctype(ret) HELPER(name) (void); 129 130 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 131 dh_ctype(ret) HELPER(name) (dh_ctype(t1)); 132 133 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 134 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)); 135 136 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 137 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)); 138 139 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 140 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ 141 dh_ctype(t4)); 142 143 #undef GEN_HELPER 144 #define GEN_HELPER -1 145 146 #elif GEN_HELPER == 1 147 /* Gen functions. */ 148 149 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 150 static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \ 151 { \ 152 int sizemask; \ 153 sizemask = dh_is_64bit(ret); \ 154 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \ 155 } 156 157 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 158 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \ 159 { \ 160 TCGArg args[1]; \ 161 int sizemask = 0; \ 162 dh_sizemask(ret, 0); \ 163 dh_arg(t1, 1); \ 164 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \ 165 } 166 167 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 168 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ 169 dh_arg_decl(t2, 2)) \ 170 { \ 171 TCGArg args[2]; \ 172 int sizemask = 0; \ 173 dh_sizemask(ret, 0); \ 174 dh_arg(t1, 1); \ 175 dh_arg(t2, 2); \ 176 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \ 177 } 178 179 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 180 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ 181 dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \ 182 { \ 183 TCGArg args[3]; \ 184 int sizemask = 0; \ 185 dh_sizemask(ret, 0); \ 186 dh_arg(t1, 1); \ 187 dh_arg(t2, 2); \ 188 dh_arg(t3, 3); \ 189 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \ 190 } 191 192 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 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), dh_arg_decl(t4, 4)) \ 195 { \ 196 TCGArg args[4]; \ 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 dh_arg(t4, 4); \ 203 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \ 204 } 205 206 #undef GEN_HELPER 207 #define GEN_HELPER -1 208 209 #elif GEN_HELPER == 2 210 /* Register helpers. */ 211 212 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 213 tcg_register_helper(HELPER(name), #name); 214 215 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 216 DEF_HELPER_FLAGS_0(name, flags, ret) 217 218 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 219 DEF_HELPER_FLAGS_0(name, flags, ret) 220 221 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 222 DEF_HELPER_FLAGS_0(name, flags, ret) 223 224 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 225 DEF_HELPER_FLAGS_0(name, flags, ret) 226 227 #undef GEN_HELPER 228 #define GEN_HELPER -1 229 230 #elif GEN_HELPER == -1 231 /* Undefine macros. */ 232 233 #undef DEF_HELPER_FLAGS_0 234 #undef DEF_HELPER_FLAGS_1 235 #undef DEF_HELPER_FLAGS_2 236 #undef DEF_HELPER_FLAGS_3 237 #undef DEF_HELPER_FLAGS_4 238 #undef GEN_HELPER 239 240 #endif 241