Home | History | Annotate | Download | only in qemu
      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