1  /* Functions and structures shared between arm and aarch64.
       2  
       3     Copyright (C) 1991-2023 Free Software Foundation, Inc.
       4     Contributed by ARM Ltd.
       5  
       6     This file is part of GCC.
       7  
       8     GCC is free software; you can redistribute it and/or modify it
       9     under the terms of the GNU General Public License as published
      10     by the Free Software Foundation; either version 3, or (at your
      11     option) any later version.
      12  
      13     GCC is distributed in the hope that it will be useful, but WITHOUT
      14     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      16     License for more details.
      17  
      18     You should have received a copy of the GNU General Public License
      19     along with GCC; see the file COPYING3.  If not see
      20     <http://www.gnu.org/licenses/>.  */
      21  
      22  
      23  #ifndef GCC_AARCH_COMMON_PROTOS_H
      24  #define GCC_AARCH_COMMON_PROTOS_H
      25  
      26  #include "hard-reg-set.h"
      27  
      28  extern int aarch_accumulator_forwarding (rtx_insn *, rtx_insn *);
      29  extern bool aarch_rev16_p (rtx);
      30  extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode);
      31  extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode);
      32  extern bool aarch_mm_needs_acquire (rtx);
      33  extern bool aarch_mm_needs_release (rtx);
      34  extern int arm_early_load_addr_dep (rtx, rtx);
      35  extern int arm_early_load_addr_dep_ptr (rtx, rtx);
      36  extern int arm_early_store_addr_dep (rtx, rtx);
      37  extern int arm_early_store_addr_dep_ptr (rtx, rtx);
      38  extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
      39  extern int arm_mac_accumulator_is_result (rtx, rtx);
      40  extern int arm_no_early_alu_shift_dep (rtx, rtx);
      41  extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
      42  extern int arm_no_early_mul_dep (rtx, rtx);
      43  extern int arm_no_early_store_addr_dep (rtx, rtx);
      44  extern bool arm_rtx_shift_left_p (rtx);
      45  extern void aarch_bti_arch_check (void);
      46  extern bool aarch_bti_enabled (void);
      47  extern bool aarch_bti_j_insn_p (rtx_insn *);
      48  extern bool aarch_pac_insn_p (rtx);
      49  extern rtx aarch_gen_bti_c (void);
      50  extern rtx aarch_gen_bti_j (void);
      51  
      52  /* RTX cost table definitions.  These are used when tuning for speed rather
      53     than for size and should reflect the _additional_ cost over the cost
      54     of the fastest instruction in the machine, which is COSTS_N_INSNS (1).
      55     Therefore it's okay for some costs to be 0.
      56     Costs may not have a negative value.  */
      57  struct alu_cost_table
      58  {
      59    const int arith;		/* ADD/SUB.  */
      60    const int logical;		/* AND/ORR/EOR/BIC, etc.  */
      61    const int shift;		/* Simple shift.  */
      62    const int shift_reg;		/* Simple shift by reg.  */
      63    const int arith_shift;	/* Additional when arith also shifts...  */
      64    const int arith_shift_reg;	/* ... and when the shift is by a reg.  */
      65    const int log_shift;		/* Additional when logic also shifts...  */
      66    const int log_shift_reg;	/* ... and when the shift is by a reg.  */
      67    const int extend;		/* Zero/sign extension.  */
      68    const int extend_arith;	/* Extend and arith.  */
      69    const int bfi;		/* Bit-field insert.  */
      70    const int bfx;		/* Bit-field extraction.  */
      71    const int clz;		/* Count Leading Zeros.  */
      72    const int rev;		/* Reverse bits/bytes.  */
      73    const int non_exec;		/* Extra cost when not executing insn.  */
      74    const bool non_exec_costs_exec; /* True if non-execution must add the exec
      75  				     cost.  */
      76  };
      77  
      78  struct mult_cost_table
      79  {
      80    const int simple;
      81    const int flag_setting;	/* Additional cost if multiply sets flags. */
      82    const int extend;
      83    const int add;
      84    const int extend_add;
      85    const int idiv;
      86  };
      87  
      88  /* Calculations of LDM costs are complex.  We assume an initial cost
      89     (ldm_1st) which will load the number of registers mentioned in
      90     ldm_regs_per_insn_1st registers; then each additional
      91     ldm_regs_per_insn_subsequent registers cost one more insn.
      92     Similarly for STM operations.
      93     Therefore the ldm_regs_per_insn_1st/stm_regs_per_insn_1st and
      94     ldm_regs_per_insn_subsequent/stm_regs_per_insn_subsequent fields indicate
      95     the number of registers loaded/stored and are expressed by a simple integer
      96     and not by a COSTS_N_INSNS (N) expression.
      97     */
      98  struct mem_cost_table
      99  {
     100    const int load;
     101    const int load_sign_extend;	/* Additional to load cost.  */
     102    const int ldrd;		/* Cost of LDRD.  */
     103    const int ldm_1st;
     104    const int ldm_regs_per_insn_1st;
     105    const int ldm_regs_per_insn_subsequent;
     106    const int loadf;		/* SFmode.  */
     107    const int loadd;		/* DFmode.  */
     108    const int load_unaligned;	/* Extra for unaligned loads.  */
     109    const int store;
     110    const int strd;
     111    const int stm_1st;
     112    const int stm_regs_per_insn_1st;
     113    const int stm_regs_per_insn_subsequent;
     114    const int storef;		/* SFmode.  */
     115    const int stored;		/* DFmode.  */
     116    const int store_unaligned;	/* Extra for unaligned stores.  */
     117    const int loadv;		/* Vector load.  */
     118    const int storev;		/* Vector store.  */
     119  };
     120  
     121  struct fp_cost_table
     122  {
     123    const int div;
     124    const int mult;
     125    const int mult_addsub;	/* Non-fused.  */
     126    const int fma;		/* Fused.  */
     127    const int addsub;
     128    const int fpconst;		/* Immediate.  */
     129    const int neg;		/* NEG and ABS.  */
     130    const int compare;
     131    const int widen;		/* Widen to this size.  */
     132    const int narrow;		/* Narrow from this size.  */
     133    const int toint;
     134    const int fromint;
     135    const int roundint;		/* V8 round to integral, remains FP format.  */
     136  };
     137  
     138  struct vector_cost_table
     139  {
     140    const int alu;
     141    const int mult;
     142    const int movi;
     143    const int dup;
     144    const int extract;
     145  };
     146  
     147  struct cpu_cost_table
     148  {
     149    const struct alu_cost_table alu;
     150    const struct mult_cost_table mult[2]; /* SImode and DImode.  */
     151    const struct mem_cost_table ldst;
     152    const struct fp_cost_table fp[2]; /* SFmode and DFmode.  */
     153    const struct vector_cost_table vect;
     154  };
     155  
     156  rtx_insn *arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
     157  			     vec<machine_mode> & /*input_modes*/,
     158  			     vec<const char *> &constraints,
     159  			     vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
     160  			     location_t loc);
     161  
     162  /* Parsing routine for branch-protection common to AArch64 and Arm.  */
     163  enum aarch_parse_opt_result aarch_parse_branch_protection (const char*, char**);
     164  
     165  /* Validation routine for branch-protection common to AArch64 and Arm.  */
     166  bool aarch_validate_mbranch_protection (const char *);
     167  
     168  #endif /* GCC_AARCH_COMMON_PROTOS_H */