qemu/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_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) \
 128dh_ctype(ret) HELPER(name) (void);
 129
 130#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
 131dh_ctype(ret) HELPER(name) (dh_ctype(t1));
 132
 133#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
 134dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
 135
 136#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
 137dh_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) \
 140dh_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) \
 150static 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) \
 158static 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) \
 168static 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) \
 180static 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) \
 193static 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) \
 213tcg_register_helper(HELPER(name), #name);
 214
 215#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
 216DEF_HELPER_FLAGS_0(name, flags, ret)
 217
 218#define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
 219DEF_HELPER_FLAGS_0(name, flags, ret)
 220
 221#define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
 222DEF_HELPER_FLAGS_0(name, flags, ret)
 223
 224#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
 225DEF_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