(root)/
gcc-13.2.0/
gcc/
optabs.h
       1  /* Definitions for code generation pass of GNU compiler.
       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_H
      21  #define GCC_OPTABS_H
      22  
      23  #include "optabs-query.h"
      24  #include "optabs-libfuncs.h"
      25  #include "vec-perm-indices.h"
      26  
      27  /* Generate code for a widening multiply.  */
      28  extern rtx expand_widening_mult (machine_mode, rtx, rtx, rtx, int, optab);
      29  
      30  /* Describes the type of an expand_operand.  Each value is associated
      31     with a create_*_operand function; see the comments above those
      32     functions for details.  */
      33  enum expand_operand_type {
      34    EXPAND_FIXED,
      35    EXPAND_OUTPUT,
      36    EXPAND_INPUT,
      37    EXPAND_CONVERT_TO,
      38    EXPAND_CONVERT_FROM,
      39    EXPAND_ADDRESS,
      40    EXPAND_INTEGER
      41  };
      42  
      43  /* Information about an operand for instruction expansion.  */
      44  class expand_operand {
      45  public:
      46    /* The type of operand.  */
      47    ENUM_BITFIELD (expand_operand_type) type : 8;
      48  
      49    /* True if any conversion should treat VALUE as being unsigned
      50       rather than signed.  Only meaningful for certain types.  */
      51    unsigned int unsigned_p : 1;
      52  
      53    /* Is the target operand.  */
      54    unsigned int target : 1;
      55  
      56    /* Unused; available for future use.  */
      57    unsigned int unused : 6;
      58  
      59    /* The mode passed to the convert_*_operand function.  It has a
      60       type-dependent meaning.  */
      61    ENUM_BITFIELD (machine_mode) mode : 16;
      62  
      63    /* The value of the operand.  */
      64    rtx value;
      65  
      66    /* The value of an EXPAND_INTEGER operand.  */
      67    poly_int64 int_value;
      68  };
      69  
      70  /* Initialize OP with the given fields.  Initialise the other fields
      71     to their default values.  */
      72  
      73  inline void
      74  create_expand_operand (class expand_operand *op,
      75  		       enum expand_operand_type type,
      76  		       rtx value, machine_mode mode,
      77  		       bool unsigned_p, poly_int64 int_value = 0)
      78  {
      79    op->type = type;
      80    op->unsigned_p = unsigned_p;
      81    op->target = 0;
      82    op->unused = 0;
      83    op->mode = mode;
      84    op->value = value;
      85    op->int_value = int_value;
      86  }
      87  
      88  /* Make OP describe an operand that must use rtx X, even if X is volatile.  */
      89  
      90  inline void
      91  create_fixed_operand (class expand_operand *op, rtx x)
      92  {
      93    create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
      94  }
      95  
      96  /* Make OP describe an output operand that must have mode MODE.
      97     X, if nonnull, is a suggestion for where the output should be stored.
      98     It is OK for VALUE to be inconsistent with MODE, although it will just
      99     be ignored in that case.  */
     100  
     101  inline void
     102  create_output_operand (class expand_operand *op, rtx x,
     103  		       machine_mode mode)
     104  {
     105    create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
     106  }
     107  
     108  /* Make OP describe an input operand that must have mode MODE and
     109     value VALUE; MODE cannot be VOIDmode.  The backend may request that
     110     VALUE be copied into a different kind of rtx before being passed
     111     as an operand.  */
     112  
     113  inline void
     114  create_input_operand (class expand_operand *op, rtx value,
     115  		      machine_mode mode)
     116  {
     117    create_expand_operand (op, EXPAND_INPUT, value, mode, false);
     118  }
     119  
     120  /* Like create_input_operand, except that VALUE must first be converted
     121     to mode MODE.  UNSIGNED_P says whether VALUE is unsigned.  */
     122  
     123  inline void
     124  create_convert_operand_to (class expand_operand *op, rtx value,
     125  			   machine_mode mode, bool unsigned_p)
     126  {
     127    create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
     128  }
     129  
     130  /* Make OP describe an input operand that should have the same value
     131     as VALUE, after any mode conversion that the backend might request.
     132     If VALUE is a CONST_INT, it should be treated as having mode MODE.
     133     UNSIGNED_P says whether VALUE is unsigned.
     134  
     135     The conversion of VALUE can include a combination of numerical
     136     conversion (as for convert_modes) and duplicating a scalar to fill
     137     a vector (if VALUE is a scalar but the operand is a vector).  */
     138  
     139  inline void
     140  create_convert_operand_from (class expand_operand *op, rtx value,
     141  			     machine_mode mode, bool unsigned_p)
     142  {
     143    create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
     144  }
     145  
     146  
     147  /* Make OP describe an input Pmode address operand.  VALUE is the value
     148     of the address, but it may need to be converted to Pmode first.  */
     149  
     150  inline void
     151  create_address_operand (class expand_operand *op, rtx value)
     152  {
     153    create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
     154  }
     155  
     156  extern void create_integer_operand (class expand_operand *, poly_int64);
     157  
     158  /* Passed to expand_simple_binop and expand_binop to say which options
     159     to try to use if the requested operation can't be open-coded on the
     160     requisite mode.  Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using
     161     a library call.  Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try
     162     using a wider mode.  OPTAB_MUST_WIDEN says try widening and don't
     163     try anything else.  */
     164  
     165  enum optab_methods
     166  {
     167    OPTAB_DIRECT,
     168    OPTAB_LIB,
     169    OPTAB_WIDEN,
     170    OPTAB_LIB_WIDEN,
     171    OPTAB_MUST_WIDEN
     172  };
     173  
     174  extern rtx expand_widen_pattern_expr (struct separate_ops *, rtx , rtx , rtx,
     175                                        rtx, int);
     176  extern rtx expand_ternary_op (machine_mode mode, optab ternary_optab,
     177  			      rtx op0, rtx op1, rtx op2, rtx target,
     178  			      int unsignedp);
     179  extern rtx simplify_expand_binop (machine_mode mode, optab binoptab,
     180  				  rtx op0, rtx op1, rtx target, int unsignedp,
     181  				  enum optab_methods methods);
     182  extern bool force_expand_binop (machine_mode, optab, rtx, rtx, rtx, int,
     183  				enum optab_methods);
     184  extern rtx expand_vector_broadcast (machine_mode, rtx);
     185  
     186  extern rtx expand_doubleword_divmod (machine_mode, rtx, rtx, rtx *, bool);
     187  
     188  /* Generate code for a simple binary or unary operation.  "Simple" in
     189     this case means "can be unambiguously described by a (mode, code)
     190     pair and mapped to a single optab."  */
     191  extern rtx expand_simple_binop (machine_mode, enum rtx_code, rtx,
     192  				rtx, rtx, int, enum optab_methods);
     193  
     194  /* Expand a binary operation given optab and rtx operands.  */
     195  extern rtx expand_binop (machine_mode, optab, rtx, rtx, rtx, int,
     196  			 enum optab_methods);
     197  
     198  /* Expand a binary operation with both signed and unsigned forms.  */
     199  extern rtx sign_expand_binop (machine_mode, optab, optab, rtx, rtx,
     200  			      rtx, int, enum optab_methods);
     201  
     202  /* Generate code to perform an operation on one operand with two results.  */
     203  extern int expand_twoval_unop (optab, rtx, rtx, rtx, int);
     204  
     205  /* Generate code to perform an operation on two operands with two results.  */
     206  extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
     207  
     208  /* Generate code to perform an operation on two operands with two
     209     results, using a library function.  */
     210  extern bool expand_twoval_binop_libfunc (optab, rtx, rtx, rtx, rtx,
     211  					 enum rtx_code);
     212  extern rtx expand_simple_unop (machine_mode, enum rtx_code, rtx, rtx,
     213  			       int);
     214  
     215  /* Expand a unary arithmetic operation given optab rtx operand.  */
     216  extern rtx expand_unop (machine_mode, optab, rtx, rtx, int);
     217  
     218  /* Expand the absolute value operation.  */
     219  extern rtx expand_abs_nojump (machine_mode, rtx, rtx, int);
     220  extern rtx expand_abs (machine_mode, rtx, rtx, int, int);
     221  
     222  /* Expand the one's complement absolute value operation.  */
     223  extern rtx expand_one_cmpl_abs_nojump (machine_mode, rtx, rtx);
     224  
     225  /* Expand the copysign operation.  */
     226  extern rtx expand_copysign (rtx, rtx, rtx);
     227  /* Generate an instruction with a given INSN_CODE with an output and
     228     an input.  */
     229  extern bool maybe_emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
     230  extern void emit_unop_insn (enum insn_code, rtx, rtx, enum rtx_code);
     231  
     232  /* Emit code to make a call to a constant function or a library call.  */
     233  extern void emit_libcall_block (rtx_insn *, rtx, rtx, rtx);
     234  
     235  /* The various uses that a comparison can have; used by can_compare_p:
     236     jumps, conditional moves, store flag operations.  */
     237  enum can_compare_purpose
     238  {
     239    ccp_jump,
     240    ccp_cmov,
     241    ccp_store_flag
     242  };
     243  
     244  /* Nonzero if a compare of mode MODE can be done straightforwardly
     245     (without splitting it into pieces).  */
     246  extern int can_compare_p (enum rtx_code, machine_mode,
     247  			  enum can_compare_purpose);
     248  
     249  /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
     250     for code CODE, comparing operands of mode VALUE_MODE and producing a result
     251     with MASK_MODE.  */
     252  extern bool can_vec_cmp_compare_p (enum rtx_code, machine_mode, machine_mode);
     253  
     254  /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
     255     code CODE, comparing operands of mode CMP_OP_MODE and producing a result
     256     with VALUE_MODE.  */
     257  extern bool can_vcond_compare_p (enum rtx_code, machine_mode, machine_mode);
     258  
     259  /* Return whether the backend can emit vector set instructions for inserting
     260     element into vector at variable index position.  */
     261  extern bool can_vec_set_var_idx_p (machine_mode);
     262  
     263  extern rtx prepare_operand (enum insn_code, rtx, int, machine_mode,
     264  			    machine_mode, int);
     265  /* Emit a pair of rtl insns to compare two rtx's and to jump
     266     to a label if the comparison is true.  */
     267  extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
     268  				     machine_mode, int, rtx,
     269  				     profile_probability prob
     270  					= profile_probability::uninitialized ());
     271  extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
     272  				     machine_mode, int, tree, rtx,
     273  				     profile_probability prob
     274  					= profile_probability::uninitialized ());
     275  
     276  /* Generate code to indirectly jump to a location given in the rtx LOC.  */
     277  extern void emit_indirect_jump (rtx);
     278  
     279  #include "insn-config.h"
     280  
     281  #ifndef GCC_INSN_CONFIG_H
     282  #error "insn-config.h must be included before optabs.h"
     283  #endif
     284  
     285  /* Emit a conditional move operation.  */
     286  rtx emit_conditional_move (rtx, rtx_comparison, rtx, rtx, machine_mode, int);
     287  rtx emit_conditional_move (rtx, rtx, rtx, rtx, rtx, machine_mode);
     288  
     289  /* Emit a conditional negate or bitwise complement operation.  */
     290  rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx,
     291  					 rtx, rtx);
     292  
     293  rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, machine_mode,
     294  			  rtx, rtx, machine_mode, int);
     295  
     296  /* Create but don't emit one rtl instruction to perform certain operations.
     297     Modes must match; operands must meet the operation's predicates.
     298     Likewise for subtraction and for just copying.  */
     299  extern rtx_insn *gen_add2_insn (rtx, rtx);
     300  extern rtx_insn *gen_add3_insn (rtx, rtx, rtx);
     301  extern int have_add2_insn (rtx, rtx);
     302  extern rtx_insn *gen_addptr3_insn (rtx, rtx, rtx);
     303  extern int have_addptr3_insn (rtx, rtx, rtx);
     304  extern rtx_insn *gen_sub2_insn (rtx, rtx);
     305  extern rtx_insn *gen_sub3_insn (rtx, rtx, rtx);
     306  extern int have_sub2_insn (rtx, rtx);
     307  
     308  /* Generate the body of an insn to extend Y (with mode MFROM)
     309     into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
     310  extern rtx_insn *gen_extend_insn (rtx, rtx, machine_mode, machine_mode, int);
     311  
     312  /* Generate code for a FLOAT_EXPR.  */
     313  extern void expand_float (rtx, rtx, int);
     314  
     315  /* Generate code for a FIX_EXPR.  */
     316  extern void expand_fix (rtx, rtx, int);
     317  
     318  /* Generate code for a FIXED_CONVERT_EXPR.  */
     319  extern void expand_fixed_convert (rtx, rtx, int, int);
     320  
     321  /* Generate code for float to integral conversion.  */
     322  extern bool expand_sfix_optab (rtx, rtx, convert_optab);
     323  
     324  /* Report whether the machine description contains an insn which can
     325     perform the operation described by CODE and MODE.  */
     326  extern int have_insn_for (enum rtx_code, machine_mode);
     327  
     328  /* Generate a conditional trap instruction.  */
     329  extern rtx_insn *gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
     330  
     331  /* Generate code for VEC_PERM_EXPR.  */
     332  extern rtx expand_vec_perm_var (machine_mode, rtx, rtx, rtx, rtx);
     333  extern rtx expand_vec_perm_const (machine_mode, rtx, rtx,
     334  				  const vec_perm_builder &, machine_mode, rtx);
     335  
     336  /* Generate code for vector comparison.  */
     337  extern rtx expand_vec_cmp_expr (tree, tree, rtx);
     338  
     339  /* Generate code for VEC_SERIES_EXPR.  */
     340  extern rtx expand_vec_series_expr (machine_mode, rtx, rtx, rtx);
     341  
     342  /* Generate code for MULT_HIGHPART_EXPR.  */
     343  extern rtx expand_mult_highpart (machine_mode, rtx, rtx, rtx, bool);
     344  
     345  extern rtx expand_sync_lock_test_and_set (rtx, rtx, rtx);
     346  extern rtx expand_atomic_test_and_set (rtx, rtx, enum memmodel);
     347  extern rtx expand_atomic_exchange (rtx, rtx, rtx, enum memmodel);
     348  extern bool expand_atomic_compare_and_swap (rtx *, rtx *, rtx, rtx, rtx, bool,
     349  					    enum memmodel, enum memmodel);
     350  /* Generate memory barriers.  */
     351  extern void expand_mem_thread_fence (enum memmodel);
     352  extern void expand_mem_signal_fence (enum memmodel);
     353  
     354  rtx expand_atomic_load (rtx, rtx, enum memmodel);
     355  rtx expand_atomic_store (rtx, rtx, enum memmodel, bool);
     356  rtx expand_atomic_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel, 
     357  			      bool);
     358  
     359  extern void expand_asm_reg_clobber_mem_blockage (HARD_REG_SET);
     360  
     361  extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
     362  				  rtx operand);
     363  extern bool valid_multiword_target_p (rtx);
     364  extern void create_convert_operand_from_type (class expand_operand *op,
     365  					      rtx value, tree type);
     366  extern bool maybe_legitimize_operands (enum insn_code icode,
     367  				       unsigned int opno, unsigned int nops,
     368  				       class expand_operand *ops);
     369  extern rtx_insn *maybe_gen_insn (enum insn_code icode, unsigned int nops,
     370  				 class expand_operand *ops);
     371  extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
     372  			       class expand_operand *ops);
     373  extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
     374  				    class expand_operand *ops);
     375  extern void expand_insn (enum insn_code icode, unsigned int nops,
     376  			 class expand_operand *ops);
     377  extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
     378  			      class expand_operand *ops);
     379  
     380  extern enum rtx_code get_rtx_code_1 (enum tree_code tcode, bool unsignedp);
     381  extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp);
     382  extern rtx vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
     383  			       tree t_op0, tree t_op1, bool unsignedp,
     384  			       enum insn_code icode, unsigned int opno);
     385  
     386  
     387  #endif /* GCC_OPTABS_H */