def-helper.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /* Helper file for declaring TCG helper functions.
  2. Should be included at the start and end of target-foo/helper.h.
  3. Targets should use DEF_HELPER_N and DEF_HELPER_FLAGS_N to declare helper
  4. functions. Names should be specified without the helper_ prefix, and
  5. the return and argument types specified. 3 basic types are understood
  6. (i32, i64 and ptr). Additional aliases are provided for convenience and
  7. to match the types used by the C helper implementation.
  8. The target helper.h should be included in all files that use/define
  9. helper functions. THis will ensure that function prototypes are
  10. consistent. In addition it should be included an extra two times for
  11. helper.c, defining:
  12. GEN_HELPER 1 to produce op generation functions (gen_helper_*)
  13. GEN_HELPER 2 to do runtime registration helper functions.
  14. */
  15. #ifndef DEF_HELPER_H
  16. #define DEF_HELPER_H 1
  17. #define HELPER(name) glue(helper_, name)
  18. #define GET_TCGV_i32 GET_TCGV_I32
  19. #define GET_TCGV_i64 GET_TCGV_I64
  20. #define GET_TCGV_ptr GET_TCGV_PTR
  21. /* Some types that make sense in C, but not for TCG. */
  22. #define dh_alias_i32 i32
  23. #define dh_alias_s32 i32
  24. #define dh_alias_int i32
  25. #define dh_alias_i64 i64
  26. #define dh_alias_s64 i64
  27. #define dh_alias_f32 i32
  28. #define dh_alias_f64 i64
  29. #if TARGET_LONG_BITS == 32
  30. #define dh_alias_tl i32
  31. #else
  32. #define dh_alias_tl i64
  33. #endif
  34. #define dh_alias_ptr ptr
  35. #define dh_alias_void void
  36. #define dh_alias_env ptr
  37. #define dh_alias(t) glue(dh_alias_, t)
  38. #define dh_ctype_i32 uint32_t
  39. #define dh_ctype_s32 int32_t
  40. #define dh_ctype_int int
  41. #define dh_ctype_i64 uint64_t
  42. #define dh_ctype_s64 int64_t
  43. #define dh_ctype_f32 float32
  44. #define dh_ctype_f64 float64
  45. #define dh_ctype_tl target_ulong
  46. #define dh_ctype_ptr void *
  47. #define dh_ctype_void void
  48. #define dh_ctype_env CPUState *
  49. #define dh_ctype(t) dh_ctype_##t
  50. /* We can't use glue() here because it falls foul of C preprocessor
  51. recursive expansion rules. */
  52. #define dh_retvar_decl0_void void
  53. #define dh_retvar_decl0_i32 TCGv_i32 retval
  54. #define dh_retvar_decl0_i64 TCGv_i64 retval
  55. #define dh_retvar_decl0_ptr TCGv_ptr retval
  56. #define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t))
  57. #define dh_retvar_decl_void
  58. #define dh_retvar_decl_i32 TCGv_i32 retval,
  59. #define dh_retvar_decl_i64 TCGv_i64 retval,
  60. #define dh_retvar_decl_ptr TCGv_ptr retval,
  61. #define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t))
  62. #define dh_retvar_void TCG_CALL_DUMMY_ARG
  63. #define dh_retvar_i32 GET_TCGV_i32(retval)
  64. #define dh_retvar_i64 GET_TCGV_i64(retval)
  65. #define dh_retvar_ptr GET_TCGV_ptr(retval)
  66. #define dh_retvar(t) glue(dh_retvar_, dh_alias(t))
  67. #define dh_is_64bit_void 0
  68. #define dh_is_64bit_i32 0
  69. #define dh_is_64bit_i64 1
  70. #define dh_is_64bit_ptr (TCG_TARGET_REG_BITS == 64)
  71. #define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t))
  72. #define dh_is_signed_void 0
  73. #define dh_is_signed_i32 0
  74. #define dh_is_signed_s32 1
  75. #define dh_is_signed_i64 0
  76. #define dh_is_signed_s64 1
  77. #define dh_is_signed_f32 0
  78. #define dh_is_signed_f64 0
  79. #define dh_is_signed_tl 0
  80. #define dh_is_signed_int 1
  81. /* ??? This is highly specific to the host cpu. There are even special
  82. extension instructions that may be required, e.g. ia64's addp4. But
  83. for now we don't support any 64-bit targets with 32-bit pointers. */
  84. #define dh_is_signed_ptr 0
  85. #define dh_is_signed_env dh_is_signed_ptr
  86. #define dh_is_signed(t) dh_is_signed_##t
  87. #define dh_sizemask(t, n) \
  88. sizemask |= dh_is_64bit(t) << (n*2); \
  89. sizemask |= dh_is_signed(t) << (n*2+1)
  90. #define dh_arg(t, n) \
  91. args[n - 1] = glue(GET_TCGV_, dh_alias(t))(glue(arg, n)); \
  92. dh_sizemask(t, n)
  93. #define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n)
  94. #define DEF_HELPER_0(name, ret) \
  95. DEF_HELPER_FLAGS_0(name, 0, ret)
  96. #define DEF_HELPER_1(name, ret, t1) \
  97. DEF_HELPER_FLAGS_1(name, 0, ret, t1)
  98. #define DEF_HELPER_2(name, ret, t1, t2) \
  99. DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2)
  100. #define DEF_HELPER_3(name, ret, t1, t2, t3) \
  101. DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3)
  102. #define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \
  103. DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4)
  104. #endif /* DEF_HELPER_H */
  105. #ifndef GEN_HELPER
  106. /* Function prototypes. */
  107. #define DEF_HELPER_FLAGS_0(name, flags, ret) \
  108. dh_ctype(ret) HELPER(name) (void);
  109. #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
  110. dh_ctype(ret) HELPER(name) (dh_ctype(t1));
  111. #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
  112. dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
  113. #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
  114. dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3));
  115. #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
  116. dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
  117. dh_ctype(t4));
  118. #undef GEN_HELPER
  119. #define GEN_HELPER -1
  120. #elif GEN_HELPER == 1
  121. /* Gen functions. */
  122. #define DEF_HELPER_FLAGS_0(name, flags, ret) \
  123. static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
  124. { \
  125. int sizemask; \
  126. sizemask = dh_is_64bit(ret); \
  127. tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 0, NULL); \
  128. }
  129. #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
  130. static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1)) \
  131. { \
  132. TCGArg args[1]; \
  133. int sizemask = 0; \
  134. dh_sizemask(ret, 0); \
  135. dh_arg(t1, 1); \
  136. tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 1, args); \
  137. }
  138. #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
  139. static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
  140. dh_arg_decl(t2, 2)) \
  141. { \
  142. TCGArg args[2]; \
  143. int sizemask = 0; \
  144. dh_sizemask(ret, 0); \
  145. dh_arg(t1, 1); \
  146. dh_arg(t2, 2); \
  147. tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 2, args); \
  148. }
  149. #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
  150. static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
  151. dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
  152. { \
  153. TCGArg args[3]; \
  154. int sizemask = 0; \
  155. dh_sizemask(ret, 0); \
  156. dh_arg(t1, 1); \
  157. dh_arg(t2, 2); \
  158. dh_arg(t3, 3); \
  159. tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 3, args); \
  160. }
  161. #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
  162. static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) dh_arg_decl(t1, 1), \
  163. dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
  164. { \
  165. TCGArg args[4]; \
  166. int sizemask = 0; \
  167. dh_sizemask(ret, 0); \
  168. dh_arg(t1, 1); \
  169. dh_arg(t2, 2); \
  170. dh_arg(t3, 3); \
  171. dh_arg(t4, 4); \
  172. tcg_gen_helperN(HELPER(name), flags, sizemask, dh_retvar(ret), 4, args); \
  173. }
  174. #undef GEN_HELPER
  175. #define GEN_HELPER -1
  176. #elif GEN_HELPER == 2
  177. /* Register helpers. */
  178. #define DEF_HELPER_FLAGS_0(name, flags, ret) \
  179. tcg_register_helper(HELPER(name), #name);
  180. #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
  181. DEF_HELPER_FLAGS_0(name, flags, ret)
  182. #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
  183. DEF_HELPER_FLAGS_0(name, flags, ret)
  184. #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \
  185. DEF_HELPER_FLAGS_0(name, flags, ret)
  186. #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
  187. DEF_HELPER_FLAGS_0(name, flags, ret)
  188. #undef GEN_HELPER
  189. #define GEN_HELPER -1
  190. #elif GEN_HELPER == -1
  191. /* Undefine macros. */
  192. #undef DEF_HELPER_FLAGS_0
  193. #undef DEF_HELPER_FLAGS_1
  194. #undef DEF_HELPER_FLAGS_2
  195. #undef DEF_HELPER_FLAGS_3
  196. #undef DEF_HELPER_FLAGS_4
  197. #undef GEN_HELPER
  198. #endif