qemu/include/exec/def-helper.h
<<
>>
Prefs
   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/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
 132
 133#endif /* DEF_HELPER_H */
 134
 135#ifndef GEN_HELPER
 136/* Function prototypes.  */
 137
 138#define DEF_HELPER_FLAGS_0(name, flags, ret) \
 139dh_ctype(ret) HELPER(name) (void);
 140
 141#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
 142dh_ctype(ret) HELPER(name) (dh_ctype(t1));
 143
 144#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
 145dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 146
 147#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
 148dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
 149
 150#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
 151dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
 152                                   dh_ctype(t4));
 153
 154#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
 155dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
 156                            dh_ctype(t4), dh_ctype(t5));
 157
 158#undef GEN_HELPER
 159#define GEN_HELPER -1
 160
 161#elif GEN_HELPER == 1
 162/* Gen functions.  */
 163
 164#define DEF_HELPER_FLAGS_0(name, flags, ret) \
 165static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
 166{ \
 167  int sizemask; \
 168  sizemask = dh_is_64bit(ret); \
 169  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \
 170}
 171
 172#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
 173static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
 174{ \
 175  TCGArg args[1]; \
 176  int sizemask = 0; \
 177  dh_sizemask(ret, 0); \
 178  dh_arg(t1, 1); \
 179  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
 180}
 181
 182#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
 183static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
 184    dh_arg_decl(t2, 2)) \
 185{ \
 186  TCGArg args[2]; \
 187  int sizemask = 0; \
 188  dh_sizemask(ret, 0); \
 189  dh_arg(t1, 1); \
 190  dh_arg(t2, 2); \
 191  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
 192}
 193
 194#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
 195static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
 196    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
 197{ \
 198  TCGArg args[3]; \
 199  int sizemask = 0; \
 200  dh_sizemask(ret, 0); \
 201  dh_arg(t1, 1); \
 202  dh_arg(t2, 2); \
 203  dh_arg(t3, 3); \
 204  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
 205}
 206
 207#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
 208static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
 209    dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
 210{ \
 211  TCGArg args[4]; \
 212  int sizemask = 0; \
 213  dh_sizemask(ret, 0); \
 214  dh_arg(t1, 1); \
 215  dh_arg(t2, 2); \
 216  dh_arg(t3, 3); \
 217  dh_arg(t4, 4); \
 218  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
 219}
 220
 221#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
 222static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
 223    dh_arg_decl(t1, 1),  dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
 224    dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
 225{ \
 226  TCGArg args[5]; \
 227  int sizemask = 0; \
 228  dh_sizemask(ret, 0); \
 229  dh_arg(t1, 1); \
 230  dh_arg(t2, 2); \
 231  dh_arg(t3, 3); \
 232  dh_arg(t4, 4); \
 233  dh_arg(t5, 5); \
 234  tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 5, args); \
 235}
 236
 237#undef GEN_HELPER
 238#define GEN_HELPER -1
 239
 240#elif GEN_HELPER == 2
 241/* Register helpers.  */
 242
 243#define DEF_HELPER_FLAGS_0(name, flags, ret) \
 244tcg_register_helper(HELPER(name), #name);
 245
 246#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
 247DEF_HELPER_FLAGS_0(name, flags, ret)
 248
 249#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
 250DEF_HELPER_FLAGS_0(name, flags, ret)
 251
 252#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
 253DEF_HELPER_FLAGS_0(name, flags, ret)
 254
 255#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
 256DEF_HELPER_FLAGS_0(name, flags, ret)
 257
 258#define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \
 259DEF_HELPER_FLAGS_0(name, flags, ret)
 260
 261#undef GEN_HELPER
 262#define GEN_HELPER -1
 263
 264#elif GEN_HELPER == -1
 265/* Undefine macros.  */
 266
 267#undef DEF_HELPER_FLAGS_0
 268#undef DEF_HELPER_FLAGS_1
 269#undef DEF_HELPER_FLAGS_2
 270#undef DEF_HELPER_FLAGS_3
 271#undef DEF_HELPER_FLAGS_4
 272#undef DEF_HELPER_FLAGS_5
 273#undef GEN_HELPER
 274
 275#endif
 276