您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

369 行
13KB

  1. /* Definitions for code generation pass of GNU compiler.
  2. Copyright (C) 2001-2020 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3, or (at your option)
  7. any later version.
  8. GCC is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #ifndef GCC_OPTABS_H
  16. #define GCC_OPTABS_H
  17. #include "optabs-query.h"
  18. #include "optabs-libfuncs.h"
  19. #include "vec-perm-indices.h"
  20. /* Generate code for a widening multiply. */
  21. extern rtx expand_widening_mult (machine_mode, rtx, rtx, rtx, int, optab);
  22. /* Describes the type of an expand_operand. Each value is associated
  23. with a create_*_operand function; see the comments above those
  24. functions for details. */
  25. enum expand_operand_type {
  26. EXPAND_FIXED,
  27. EXPAND_OUTPUT,
  28. EXPAND_INPUT,
  29. EXPAND_CONVERT_TO,
  30. EXPAND_CONVERT_FROM,
  31. EXPAND_ADDRESS,
  32. EXPAND_INTEGER
  33. };
  34. /* Information about an operand for instruction expansion. */
  35. class expand_operand {
  36. public:
  37. /* The type of operand. */
  38. ENUM_BITFIELD (expand_operand_type) type : 8;
  39. /* True if any conversion should treat VALUE as being unsigned
  40. rather than signed. Only meaningful for certain types. */
  41. unsigned int unsigned_p : 1;
  42. /* Is the target operand. */
  43. unsigned int target : 1;
  44. /* Unused; available for future use. */
  45. unsigned int unused : 6;
  46. /* The mode passed to the convert_*_operand function. It has a
  47. type-dependent meaning. */
  48. ENUM_BITFIELD (machine_mode) mode : 16;
  49. /* The value of the operand. */
  50. rtx value;
  51. /* The value of an EXPAND_INTEGER operand. */
  52. poly_int64 int_value;
  53. };
  54. /* Initialize OP with the given fields. Initialise the other fields
  55. to their default values. */
  56. static inline void
  57. create_expand_operand (class expand_operand *op,
  58. enum expand_operand_type type,
  59. rtx value, machine_mode mode,
  60. bool unsigned_p, poly_int64 int_value = 0)
  61. {
  62. op->type = type;
  63. op->unsigned_p = unsigned_p;
  64. op->target = 0;
  65. op->unused = 0;
  66. op->mode = mode;
  67. op->value = value;
  68. op->int_value = int_value;
  69. }
  70. /* Make OP describe an operand that must use rtx X, even if X is volatile. */
  71. static inline void
  72. create_fixed_operand (class expand_operand *op, rtx x)
  73. {
  74. create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
  75. }
  76. /* Make OP describe an output operand that must have mode MODE.
  77. X, if nonnull, is a suggestion for where the output should be stored.
  78. It is OK for VALUE to be inconsistent with MODE, although it will just
  79. be ignored in that case. */
  80. static inline void
  81. create_output_operand (class expand_operand *op, rtx x,
  82. machine_mode mode)
  83. {
  84. create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
  85. }
  86. /* Make OP describe an input operand that must have mode MODE and
  87. value VALUE; MODE cannot be VOIDmode. The backend may request that
  88. VALUE be copied into a different kind of rtx before being passed
  89. as an operand. */
  90. static inline void
  91. create_input_operand (class expand_operand *op, rtx value,
  92. machine_mode mode)
  93. {
  94. create_expand_operand (op, EXPAND_INPUT, value, mode, false);
  95. }
  96. /* Like create_input_operand, except that VALUE must first be converted
  97. to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */
  98. static inline void
  99. create_convert_operand_to (class expand_operand *op, rtx value,
  100. machine_mode mode, bool unsigned_p)
  101. {
  102. create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
  103. }
  104. /* Make OP describe an input operand that should have the same value
  105. as VALUE, after any mode conversion that the backend might request.
  106. If VALUE is a CONST_INT, it should be treated as having mode MODE.
  107. UNSIGNED_P says whether VALUE is unsigned.
  108. The conversion of VALUE can include a combination of numerical
  109. conversion (as for convert_modes) and duplicating a scalar to fill
  110. a vector (if VALUE is a scalar but the operand is a vector). */
  111. static inline void
  112. create_convert_operand_from (class expand_operand *op, rtx value,
  113. machine_mode mode, bool unsigned_p)
  114. {
  115. create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
  116. }
  117. /* Make OP describe an input Pmode address operand. VALUE is the value
  118. of the address, but it may need to be converted to Pmode first. */
  119. static inline void
  120. create_address_operand (class expand_operand *op, rtx value)
  121. {
  122. create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
  123. }
  124. extern void create_integer_operand (class expand_operand *, poly_int64);
  125. /* Passed to expand_simple_binop and expand_binop to say which options
  126. to try to use if the requested operation can't be open-coded on the
  127. requisite mode. Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using
  128. a library call. Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try
  129. using a wider mode. OPTAB_MUST_WIDEN says try widening and don't
  130. try anything else. */
  131. enum optab_methods
  132. {
  133. OPTAB_DIRECT,
  134. OPTAB_LIB,
  135. OPTAB_WIDEN,
  136. OPTAB_LIB_WIDEN,
  137. OPTAB_MUST_WIDEN
  138. };
  139. extern rtx expand_widen_pattern_expr (struct separate_ops *, rtx , rtx , rtx,
  140. rtx, int);
  141. extern rtx expand_ternary_op (machine_mode mode, optab ternary_optab,
  142. rtx op0, rtx op1, rtx op2, rtx target,
  143. int unsignedp);
  144. extern rtx simplify_expand_binop (machine_mode mode, optab binoptab,
  145. rtx op0, rtx op1, rtx target, int unsignedp,
  146. enum optab_methods methods);
  147. extern bool force_expand_binop (machine_mode, optab, rtx, rtx, rtx, int,
  148. enum optab_methods);
  149. extern rtx expand_vector_broadcast (machine_mode, rtx);
  150. /* Generate code for a simple binary or unary operation. "Simple" in
  151. this case means "can be unambiguously described by a (mode, code)
  152. pair and mapped to a single optab." */
  153. extern rtx expand_simple_binop (machine_mode, enum rtx_code, rtx,
  154. rtx, rtx, int, enum optab_methods);
  155. /* Expand a binary operation given optab and rtx operands. */
  156. extern rtx expand_binop (machine_mode, optab, rtx, rtx, rtx, int,
  157. enum optab_methods);
  158. /* Expand a binary operation with both signed and unsigned forms. */
  159. extern rtx sign_expand_binop (machine_mode, optab, optab, rtx, rtx,
  160. rtx, int, enum optab_methods);
  161. /* Generate code to perform an operation on one operand with two results. */
  162. extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
  163. /* Generate code to perform an operation on two operands with two results. */
  164. extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
  165. /* Generate code to perform an operation on two operands with two
  166. results, using a library function. */
  167. extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
  168. enum rtx_code);
  169. extern rtx expand_simple_unop (machine_mode, enum rtx_code, rtx, rtx,
  170. int);
  171. /* Expand a unary arithmetic operation given optab rtx operand. */
  172. extern rtx expand_unop (machine_mode, optab, rtx, rtx, int);
  173. /* Expand the absolute value operation. */
  174. extern rtx expand_abs_nojump (machine_mode, rtx, rtx, int);
  175. extern rtx expand_abs (machine_mode, rtx, rtx, int, int);
  176. /* Expand the one's complement absolute value operation. */
  177. extern rtx expand_one_cmpl_abs_nojump (machine_mode, rtx, rtx);
  178. /* Expand the copysign operation. */
  179. extern rtx expand_copysign (rtx, rtx, rtx);
  180. /* Generate an instruction with a given INSN_CODE with an output and
  181. an input. */
  182. extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
  183. extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
  184. /* Emit code to make a call to a constant function or a library call. */
  185. extern void emit_libcall_block (rtx_insn *, rtx, rtx, rtx);
  186. /* The various uses that a comparison can have; used by can_compare_p:
  187. jumps, conditional moves, store flag operations. */
  188. enum can_compare_purpose
  189. {
  190. ccp_jump,
  191. ccp_cmov,
  192. ccp_store_flag
  193. };
  194. /* Nonzero if a compare of mode MODE can be done straightforwardly
  195. (without splitting it into pieces). */
  196. extern int can_compare_p (enum rtx_code, machine_mode,
  197. enum can_compare_purpose);
  198. /* Return whether the backend can emit a vector comparison for code CODE,
  199. comparing operands of mode CMP_OP_MODE and producing a result with
  200. VALUE_MODE. */
  201. extern bool can_vcond_compare_p (enum rtx_code, machine_mode, machine_mode);
  202. extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode,
  203. machine_mode, int);
  204. /* Emit a pair of rtl insns to compare two rtx's and to jump
  205. to a label if the comparison is true. */
  206. extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
  207. machine_mode, int, rtx,
  208. profile_probability prob
  209. = profile_probability::uninitialized ());
  210. /* Generate code to indirectly jump to a location given in the rtx LOC. */
  211. extern void emit_indirect_jump (rtx);
  212. #include "insn-config.h"
  213. #ifndef GCC_INSN_CONFIG_H
  214. #error "insn-config.h must be included before optabs.h"
  215. #endif
  216. /* Emit a conditional move operation. */
  217. rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode,
  218. rtx, rtx, machine_mode, int);
  219. /* Emit a conditional negate or bitwise complement operation. */
  220. rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx,
  221. rtx, rtx);
  222. rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, machine_mode,
  223. rtx, rtx, machine_mode, int);
  224. /* Create but don't emit one rtl instruction to perform certain operations.
  225. Modes must match; operands must meet the operation's predicates.
  226. Likewise for subtraction and for just copying. */
  227. extern rtx_insn *gen_add2_insn (rtx, rtx);
  228. extern rtx_insn *gen_add3_insn (rtx, rtx, rtx);
  229. extern int have_add2_insn (rtx, rtx);
  230. extern rtx_insn *gen_addptr3_insn (rtx, rtx, rtx);
  231. extern int have_addptr3_insn (rtx, rtx, rtx);
  232. extern rtx_insn *gen_sub2_insn (rtx, rtx);
  233. extern rtx_insn *gen_sub3_insn (rtx, rtx, rtx);
  234. extern int have_sub2_insn (rtx, rtx);
  235. /* Generate the body of an insn to extend Y (with mode MFROM)
  236. into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
  237. extern rtx_insn *gen_extend_insn (rtx, rtx, machine_mode, machine_mode, int);
  238. /* Generate code for a FLOAT_EXPR. */
  239. extern void expand_float (rtx, rtx, int);
  240. /* Generate code for a FIX_EXPR. */
  241. extern void expand_fix (rtx, rtx, int);
  242. /* Generate code for a FIXED_CONVERT_EXPR. */
  243. extern void expand_fixed_convert (rtx, rtx, int, int);
  244. /* Generate code for float to integral conversion. */
  245. extern bool expand_sfix_optab (rtx, rtx, convert_optab);
  246. /* Report whether the machine description contains an insn which can
  247. perform the operation described by CODE and MODE. */
  248. extern int have_insn_for (enum rtx_code, machine_mode);
  249. /* Generate a conditional trap instruction. */
  250. extern rtx_insn *gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
  251. /* Generate code for VEC_PERM_EXPR. */
  252. extern rtx expand_vec_perm_var (machine_mode, rtx, rtx, rtx, rtx);
  253. extern rtx expand_vec_perm_const (machine_mode, rtx, rtx,
  254. const vec_perm_builder &, machine_mode, rtx);
  255. /* Generate code for vector comparison. */
  256. extern rtx expand_vec_cmp_expr (tree, tree, rtx);
  257. /* Generate code for VEC_COND_EXPR. */
  258. extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
  259. /* Generate code for VEC_SERIES_EXPR. */
  260. extern rtx expand_vec_series_expr (machine_mode, rtx, rtx, rtx);
  261. /* Generate code for MULT_HIGHPART_EXPR. */
  262. extern rtx expand_mult_highpart (machine_mode, rtx, rtx, rtx, bool);
  263. extern rtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
  264. extern rtx expand_atomic_test_and_set (rtx, rtx, enum memmodel);
  265. extern rtx expand_atomic_exchange (rtx, rtx, rtx, enum memmodel);
  266. extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
  267. enum memmodel, enum memmodel);
  268. /* Generate memory barriers. */
  269. extern void expand_mem_thread_fence (enum memmodel);
  270. extern void expand_mem_signal_fence (enum memmodel);
  271. rtx expand_atomic_load (rtx, rtx, enum memmodel);
  272. rtx expand_atomic_store (rtx, rtx, enum memmodel, bool);
  273. rtx expand_atomic_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel,
  274. bool);
  275. extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
  276. rtx operand);
  277. extern bool valid_multiword_target_p (rtx);
  278. extern void create_convert_operand_from_type (class expand_operand *op,
  279. rtx value, tree type);
  280. extern bool maybe_legitimize_operands (enum insn_code icode,
  281. unsigned int opno, unsigned int nops,
  282. class expand_operand *ops);
  283. extern rtx_insn *maybe_gen_insn (enum insn_code icode, unsigned int nops,
  284. class expand_operand *ops);
  285. extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
  286. class expand_operand *ops);
  287. extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
  288. class expand_operand *ops);
  289. extern void expand_insn (enum insn_code icode, unsigned int nops,
  290. class expand_operand *ops);
  291. extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
  292. class expand_operand *ops);
  293. extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp);
  294. #endif /* GCC_OPTABS_H */