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_arg(t, n) \ 85 args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \ 86 sizemask |= dh_is_64bit(t) << n 87 88 #define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n) 89 90 91 #define DEF_HELPER_0(name, ret) \ 92 DEF_HELPER_FLAGS_0(name, 0, ret) 93 #define DEF_HELPER_1(name, ret, t1) \ 94 DEF_HELPER_FLAGS_1(name, 0, ret, t1) 95 #define DEF_HELPER_2(name, ret, t1, t2) \ 96 DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2) 97 #define DEF_HELPER_3(name, ret, t1, t2, t3) \ 98 DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3) 99 #define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \ 100 DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4) 101 102 #endif /* DEF_HELPER_H */ 103 104 #ifndef GEN_HELPER 105 /* Function prototypes. */ 106 107 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 108 dh_ctype(ret) HELPER(name) (void); 109 110 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 111 dh_ctype(ret) HELPER(name) (dh_ctype(t1)); 112 113 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 114 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)); 115 116 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 117 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)); 118 119 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 120 dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \ 121 dh_ctype(t4)); 122 123 #undef GEN_HELPER 124 #define GEN_HELPER -1 125 126 #elif GEN_HELPER == 1 127 /* Gen functions. */ 128 129 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 130 static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \ 131 { \ 132 int sizemask; \ 133 sizemask = dh_is_64bit(ret); \ 134 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \ 135 } 136 137 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 138 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \ 139 { \ 140 TCGArg args[1]; \ 141 int sizemask; \ 142 sizemask = dh_is_64bit(ret); \ 143 dh_arg(t1, 1); \ 144 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \ 145 } 146 147 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 148 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ 149 dh_arg_decl(t2, 2)) \ 150 { \ 151 TCGArg args[2]; \ 152 int sizemask; \ 153 sizemask = dh_is_64bit(ret); \ 154 dh_arg(t1, 1); \ 155 dh_arg(t2, 2); \ 156 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \ 157 } 158 159 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 160 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ 161 dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \ 162 { \ 163 TCGArg args[3]; \ 164 int sizemask; \ 165 sizemask = dh_is_64bit(ret); \ 166 dh_arg(t1, 1); \ 167 dh_arg(t2, 2); \ 168 dh_arg(t3, 3); \ 169 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \ 170 } 171 172 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 173 static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \ 174 dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \ 175 { \ 176 TCGArg args[4]; \ 177 int sizemask; \ 178 sizemask = dh_is_64bit(ret); \ 179 dh_arg(t1, 1); \ 180 dh_arg(t2, 2); \ 181 dh_arg(t3, 3); \ 182 dh_arg(t4, 4); \ 183 tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \ 184 } 185 186 #undef GEN_HELPER 187 #define GEN_HELPER -1 188 189 #elif GEN_HELPER == 2 190 /* Register helpers. */ 191 192 #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 193 tcg_register_helper(HELPER(name), #name); 194 195 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 196 DEF_HELPER_FLAGS_0(name, flags, ret) 197 198 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 199 DEF_HELPER_FLAGS_0(name, flags, ret) 200 201 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 202 DEF_HELPER_FLAGS_0(name, flags, ret) 203 204 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 205 DEF_HELPER_FLAGS_0(name, flags, ret) 206 207 #undef GEN_HELPER 208 #define GEN_HELPER -1 209 210 #elif GEN_HELPER == -1 211 /* Undefine macros. */ 212 213 #undef DEF_HELPER_FLAGS_0 214 #undef DEF_HELPER_FLAGS_1 215 #undef DEF_HELPER_FLAGS_2 216 #undef DEF_HELPER_FLAGS_3 217 #undef DEF_HELPER_FLAGS_4 218 #undef GEN_HELPER 219 220 #endif 221