optabs-query.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* IR-agnostic target query functions relating to optabs
  2. Copyright (C) 2001-2019 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_QUERY_H
  16. #define GCC_OPTABS_QUERY_H
  17. #include "insn-opinit.h"
  18. #include "target.h"
  19. /* Return true if OP is a conversion optab. */
  20. inline bool
  21. convert_optab_p (optab op)
  22. {
  23. return op > unknown_optab && op <= LAST_CONV_OPTAB;
  24. }
  25. /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
  26. if the target does not have such an insn. */
  27. inline enum insn_code
  28. optab_handler (optab op, machine_mode mode)
  29. {
  30. unsigned scode = (op << 16) | mode;
  31. gcc_assert (op > LAST_CONV_OPTAB);
  32. return raw_optab_handler (scode);
  33. }
  34. /* Return the insn used to perform conversion OP from mode FROM_MODE
  35. to mode TO_MODE; return CODE_FOR_nothing if the target does not have
  36. such an insn. */
  37. inline enum insn_code
  38. convert_optab_handler (convert_optab op, machine_mode to_mode,
  39. machine_mode from_mode)
  40. {
  41. unsigned scode = (op << 16) | (from_mode << 8) | to_mode;
  42. gcc_assert (convert_optab_p (op));
  43. return raw_optab_handler (scode);
  44. }
  45. enum insn_code convert_optab_handler (convert_optab, machine_mode,
  46. machine_mode, optimization_type);
  47. /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
  48. if the target does not have such an insn. */
  49. inline enum insn_code
  50. direct_optab_handler (direct_optab op, machine_mode mode)
  51. {
  52. return optab_handler (op, mode);
  53. }
  54. enum insn_code direct_optab_handler (convert_optab, machine_mode,
  55. optimization_type);
  56. /* Return true if UNOPTAB is for a trapping-on-overflow operation. */
  57. inline bool
  58. trapv_unoptab_p (optab unoptab)
  59. {
  60. return (unoptab == negv_optab
  61. || unoptab == absv_optab);
  62. }
  63. /* Return true if BINOPTAB is for a trapping-on-overflow operation. */
  64. inline bool
  65. trapv_binoptab_p (optab binoptab)
  66. {
  67. return (binoptab == addv_optab
  68. || binoptab == subv_optab
  69. || binoptab == smulv_optab);
  70. }
  71. /* Return insn code for a comparison operator with VMODE
  72. resultin MASK_MODE, unsigned if UNS is true. */
  73. static inline enum insn_code
  74. get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns)
  75. {
  76. optab tab = uns ? vec_cmpu_optab : vec_cmp_optab;
  77. return convert_optab_handler (tab, vmode, mask_mode);
  78. }
  79. /* Return insn code for a comparison operator with VMODE
  80. resultin MASK_MODE (only for EQ/NE). */
  81. static inline enum insn_code
  82. get_vec_cmp_eq_icode (machine_mode vmode, machine_mode mask_mode)
  83. {
  84. return convert_optab_handler (vec_cmpeq_optab, vmode, mask_mode);
  85. }
  86. /* Return insn code for a conditional operator with a comparison in
  87. mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE. */
  88. inline enum insn_code
  89. get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns)
  90. {
  91. enum insn_code icode = CODE_FOR_nothing;
  92. if (uns)
  93. icode = convert_optab_handler (vcondu_optab, vmode, cmode);
  94. else
  95. icode = convert_optab_handler (vcond_optab, vmode, cmode);
  96. return icode;
  97. }
  98. /* Return insn code for a conditional operator with a mask mode
  99. MMODE resulting in a value of mode VMODE. */
  100. static inline enum insn_code
  101. get_vcond_mask_icode (machine_mode vmode, machine_mode mmode)
  102. {
  103. return convert_optab_handler (vcond_mask_optab, vmode, mmode);
  104. }
  105. /* Return insn code for a conditional operator with a comparison in
  106. mode CMODE (only EQ/NE), resulting in a value of mode VMODE. */
  107. static inline enum insn_code
  108. get_vcond_eq_icode (machine_mode vmode, machine_mode cmode)
  109. {
  110. return convert_optab_handler (vcondeq_optab, vmode, cmode);
  111. }
  112. /* Enumerates the possible extraction_insn operations. */
  113. enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
  114. /* Describes an instruction that inserts or extracts a bitfield. */
  115. struct extraction_insn
  116. {
  117. /* The code of the instruction. */
  118. enum insn_code icode;
  119. /* The mode that the structure operand should have. This is byte_mode
  120. when using the legacy insv, extv and extzv patterns to access memory.
  121. If no mode is given, the structure is a BLKmode memory. */
  122. opt_scalar_int_mode struct_mode;
  123. /* The mode of the field to be inserted or extracted, and by extension
  124. the mode of the insertion or extraction itself. */
  125. scalar_int_mode field_mode;
  126. /* The mode of the field's bit position. This is only important
  127. when the position is variable rather than constant. */
  128. scalar_int_mode pos_mode;
  129. };
  130. bool get_best_reg_extraction_insn (extraction_insn *,
  131. enum extraction_pattern,
  132. unsigned HOST_WIDE_INT, machine_mode);
  133. bool get_best_mem_extraction_insn (extraction_insn *,
  134. enum extraction_pattern,
  135. HOST_WIDE_INT, HOST_WIDE_INT, machine_mode);
  136. enum insn_code can_extend_p (machine_mode, machine_mode, int);
  137. enum insn_code can_float_p (machine_mode, machine_mode, int);
  138. enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *);
  139. bool can_conditionally_move_p (machine_mode mode);
  140. opt_machine_mode qimode_for_vec_perm (machine_mode);
  141. bool selector_fits_mode_p (machine_mode, const vec_perm_indices &);
  142. bool can_vec_perm_var_p (machine_mode);
  143. bool can_vec_perm_const_p (machine_mode, const vec_perm_indices &,
  144. bool = true);
  145. /* Find a widening optab even if it doesn't widen as much as we want. */
  146. #define find_widening_optab_handler(A, B, C) \
  147. find_widening_optab_handler_and_mode (A, B, C, NULL)
  148. enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode,
  149. machine_mode,
  150. machine_mode *);
  151. int can_mult_highpart_p (machine_mode, bool);
  152. bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool);
  153. bool can_compare_and_swap_p (machine_mode, bool);
  154. bool can_atomic_exchange_p (machine_mode, bool);
  155. bool can_atomic_load_p (machine_mode);
  156. bool lshift_cheap_p (bool);
  157. bool supports_vec_gather_load_p ();
  158. bool supports_vec_scatter_store_p ();
  159. /* Version of find_widening_optab_handler_and_mode that operates on
  160. specific mode types. */
  161. template<typename T>
  162. inline enum insn_code
  163. find_widening_optab_handler_and_mode (optab op, const T &to_mode,
  164. const T &from_mode, T *found_mode)
  165. {
  166. machine_mode tmp;
  167. enum insn_code icode = find_widening_optab_handler_and_mode
  168. (op, machine_mode (to_mode), machine_mode (from_mode), &tmp);
  169. if (icode != CODE_FOR_nothing && found_mode)
  170. *found_mode = as_a <T> (tmp);
  171. return icode;
  172. }
  173. #endif