(root)/
gcc-13.2.0/
gcc/
optabs-query.h
       1  /* IR-agnostic target query functions relating to optabs
       2     Copyright (C) 2001-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC is free software; you can redistribute it and/or modify
       7  it under the terms of the GNU General Public License as published by
       8  the Free Software Foundation; either version 3, or (at your option)
       9  any later version.
      10  
      11  GCC is distributed in the hope that it will be useful,
      12  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  GNU General Public License for more details.
      15  
      16  You should have received a copy of the GNU General Public License
      17  along with GCC; see the file COPYING3.  If not see
      18  <http://www.gnu.org/licenses/>.  */
      19  
      20  #ifndef GCC_OPTABS_QUERY_H
      21  #define GCC_OPTABS_QUERY_H
      22  
      23  #include "insn-opinit.h"
      24  #include "target.h"
      25  
      26  /* Return true if OP is a conversion optab.  */
      27  
      28  inline bool
      29  convert_optab_p (optab op)
      30  {
      31    return op > unknown_optab && op <= LAST_CONV_OPTAB;
      32  }
      33  
      34  /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
      35     if the target does not have such an insn.  */
      36  
      37  inline enum insn_code
      38  optab_handler (optab op, machine_mode mode)
      39  {
      40    unsigned scode = (op << 16) | mode;
      41    gcc_assert (op > LAST_CONV_OPTAB);
      42    return raw_optab_handler (scode);
      43  }
      44  
      45  /* Return the insn used to perform conversion OP from mode FROM_MODE
      46     to mode TO_MODE; return CODE_FOR_nothing if the target does not have
      47     such an insn.  */
      48  
      49  inline enum insn_code
      50  convert_optab_handler (convert_optab op, machine_mode to_mode,
      51  		       machine_mode from_mode)
      52  {
      53    unsigned scode = (op << 16) | (from_mode << 8) | to_mode;
      54    gcc_assert (convert_optab_p (op));
      55    return raw_optab_handler (scode);
      56  }
      57  
      58  enum insn_code convert_optab_handler (convert_optab, machine_mode,
      59  				      machine_mode, optimization_type);
      60  
      61  /* Return the insn used to implement mode MODE of OP, or CODE_FOR_nothing
      62     if the target does not have such an insn.  */
      63  
      64  inline enum insn_code
      65  direct_optab_handler (direct_optab op, machine_mode mode)
      66  {
      67    return optab_handler (op, mode);
      68  }
      69  
      70  enum insn_code direct_optab_handler (convert_optab, machine_mode,
      71  				     optimization_type);
      72  
      73  /* Return true if UNOPTAB is for a trapping-on-overflow operation.  */
      74  
      75  inline bool
      76  trapv_unoptab_p (optab unoptab)
      77  {
      78    return (unoptab == negv_optab
      79  	  || unoptab == absv_optab);
      80  }
      81  
      82  /* Return true if BINOPTAB is for a trapping-on-overflow operation.  */
      83  
      84  inline bool
      85  trapv_binoptab_p (optab binoptab)
      86  {
      87    return (binoptab == addv_optab
      88  	  || binoptab == subv_optab
      89  	  || binoptab == smulv_optab);
      90  }
      91  
      92  /* Return insn code for a comparison operator with VMODE
      93     resultin MASK_MODE, unsigned if UNS is true.  */
      94  
      95  inline enum insn_code
      96  get_vec_cmp_icode (machine_mode vmode, machine_mode mask_mode, bool uns)
      97  {
      98    optab tab = uns ? vec_cmpu_optab : vec_cmp_optab;
      99    return convert_optab_handler (tab, vmode, mask_mode);
     100  }
     101  
     102  /* Return insn code for a comparison operator with VMODE
     103     resultin MASK_MODE (only for EQ/NE).  */
     104  
     105  inline enum insn_code
     106  get_vec_cmp_eq_icode (machine_mode vmode, machine_mode mask_mode)
     107  {
     108    return convert_optab_handler (vec_cmpeq_optab, vmode, mask_mode);
     109  }
     110  
     111  /* Return insn code for a conditional operator with a comparison in
     112     mode CMODE, unsigned if UNS is true, resulting in a value of mode VMODE.  */
     113  
     114  inline enum insn_code
     115  get_vcond_icode (machine_mode vmode, machine_mode cmode, bool uns)
     116  {
     117    enum insn_code icode = CODE_FOR_nothing;
     118    if (uns)
     119      icode = convert_optab_handler (vcondu_optab, vmode, cmode);
     120    else
     121      icode = convert_optab_handler (vcond_optab, vmode, cmode);
     122    return icode;
     123  }
     124  
     125  /* Return insn code for a conditional operator with a mask mode
     126     MMODE resulting in a value of mode VMODE.  */
     127  
     128  inline enum insn_code
     129  get_vcond_mask_icode (machine_mode vmode, machine_mode mmode)
     130  {
     131    return convert_optab_handler (vcond_mask_optab, vmode, mmode);
     132  }
     133  
     134  /* Return insn code for a conditional operator with a comparison in
     135     mode CMODE (only EQ/NE), resulting in a value of mode VMODE.  */
     136  
     137  inline enum insn_code
     138  get_vcond_eq_icode (machine_mode vmode, machine_mode cmode)
     139  {
     140    return convert_optab_handler (vcondeq_optab, vmode, cmode);
     141  }
     142  
     143  /* Enumerates the possible extraction_insn operations.  */
     144  enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
     145  
     146  /* Describes an instruction that inserts or extracts a bitfield.  */
     147  class extraction_insn
     148  {
     149  public:
     150    /* The code of the instruction.  */
     151    enum insn_code icode;
     152  
     153    /* The mode that the structure operand should have.  This is byte_mode
     154       when using the legacy insv, extv and extzv patterns to access memory.
     155       If no mode is given, the structure is a BLKmode memory.  */
     156    opt_scalar_int_mode struct_mode;
     157  
     158    /* The mode of the field to be inserted or extracted, and by extension
     159       the mode of the insertion or extraction itself.  */
     160    scalar_int_mode field_mode;
     161  
     162    /* The mode of the field's bit position.  This is only important
     163       when the position is variable rather than constant.  */
     164    scalar_int_mode pos_mode;
     165  };
     166  
     167  bool get_best_reg_extraction_insn (extraction_insn *,
     168  				   enum extraction_pattern,
     169  				   unsigned HOST_WIDE_INT, machine_mode);
     170  bool get_best_mem_extraction_insn (extraction_insn *,
     171  				   enum extraction_pattern,
     172  				   HOST_WIDE_INT, HOST_WIDE_INT, machine_mode);
     173  
     174  enum insn_code can_extend_p (machine_mode, machine_mode, int);
     175  enum insn_code can_float_p (machine_mode, machine_mode, int);
     176  enum insn_code can_fix_p (machine_mode, machine_mode, int, bool *);
     177  bool can_conditionally_move_p (machine_mode mode);
     178  opt_machine_mode qimode_for_vec_perm (machine_mode);
     179  bool selector_fits_mode_p (machine_mode, const vec_perm_indices &);
     180  bool can_vec_perm_var_p (machine_mode);
     181  bool can_vec_perm_const_p (machine_mode, machine_mode,
     182  			   const vec_perm_indices &, bool = true);
     183  /* Find a widening optab even if it doesn't widen as much as we want.  */
     184  #define find_widening_optab_handler(A, B, C) \
     185    find_widening_optab_handler_and_mode (A, B, C, NULL)
     186  enum insn_code find_widening_optab_handler_and_mode (optab, machine_mode,
     187  						     machine_mode,
     188  						     machine_mode *);
     189  int can_mult_highpart_p (machine_mode, bool);
     190  bool can_vec_mask_load_store_p (machine_mode, machine_mode, bool);
     191  opt_machine_mode get_len_load_store_mode (machine_mode, bool);
     192  bool can_compare_and_swap_p (machine_mode, bool);
     193  bool can_atomic_exchange_p (machine_mode, bool);
     194  bool can_atomic_load_p (machine_mode);
     195  bool lshift_cheap_p (bool);
     196  bool supports_vec_gather_load_p (machine_mode = E_VOIDmode);
     197  bool supports_vec_scatter_store_p (machine_mode = E_VOIDmode);
     198  bool can_vec_extract (machine_mode, machine_mode);
     199  
     200  /* Version of find_widening_optab_handler_and_mode that operates on
     201     specific mode types.  */
     202  
     203  template<typename T>
     204  inline enum insn_code
     205  find_widening_optab_handler_and_mode (optab op, const T &to_mode,
     206  				      const T &from_mode, T *found_mode)
     207  {
     208    machine_mode tmp;
     209    enum insn_code icode = find_widening_optab_handler_and_mode
     210      (op, machine_mode (to_mode), machine_mode (from_mode), &tmp);
     211    if (icode != CODE_FOR_nothing && found_mode)
     212      *found_mode = as_a <T> (tmp);
     213    return icode;
     214  }
     215  
     216  #endif