1 /* Functions and structures shared between arm and aarch64.
2 
3    Copyright (C) 1991-2020 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 
46 /* RTX cost table definitions.  These are used when tuning for speed rather
47    than for size and should reflect the _additional_ cost over the cost
48    of the fastest instruction in the machine, which is COSTS_N_INSNS (1).
49    Therefore it's okay for some costs to be 0.
50    Costs may not have a negative value.  */
51 struct alu_cost_table
52 {
53   const int arith;		/* ADD/SUB.  */
54   const int logical;		/* AND/ORR/EOR/BIC, etc.  */
55   const int shift;		/* Simple shift.  */
56   const int shift_reg;		/* Simple shift by reg.  */
57   const int arith_shift;	/* Additional when arith also shifts...  */
58   const int arith_shift_reg;	/* ... and when the shift is by a reg.  */
59   const int log_shift;		/* Additional when logic also shifts...  */
60   const int log_shift_reg;	/* ... and when the shift is by a reg.  */
61   const int extend;		/* Zero/sign extension.  */
62   const int extend_arith;	/* Extend and arith.  */
63   const int bfi;		/* Bit-field insert.  */
64   const int bfx;		/* Bit-field extraction.  */
65   const int clz;		/* Count Leading Zeros.  */
66   const int rev;		/* Reverse bits/bytes.  */
67   const int non_exec;		/* Extra cost when not executing insn.  */
68   const bool non_exec_costs_exec; /* True if non-execution must add the exec
69 				     cost.  */
70 };
71 
72 struct mult_cost_table
73 {
74   const int simple;
75   const int flag_setting;	/* Additional cost if multiply sets flags. */
76   const int extend;
77   const int add;
78   const int extend_add;
79   const int idiv;
80 };
81 
82 /* Calculations of LDM costs are complex.  We assume an initial cost
83    (ldm_1st) which will load the number of registers mentioned in
84    ldm_regs_per_insn_1st registers; then each additional
85    ldm_regs_per_insn_subsequent registers cost one more insn.
86    Similarly for STM operations.
87    Therefore the ldm_regs_per_insn_1st/stm_regs_per_insn_1st and
88    ldm_regs_per_insn_subsequent/stm_regs_per_insn_subsequent fields indicate
89    the number of registers loaded/stored and are expressed by a simple integer
90    and not by a COSTS_N_INSNS (N) expression.
91    */
92 struct mem_cost_table
93 {
94   const int load;
95   const int load_sign_extend;	/* Additional to load cost.  */
96   const int ldrd;		/* Cost of LDRD.  */
97   const int ldm_1st;
98   const int ldm_regs_per_insn_1st;
99   const int ldm_regs_per_insn_subsequent;
100   const int loadf;		/* SFmode.  */
101   const int loadd;		/* DFmode.  */
102   const int load_unaligned;	/* Extra for unaligned loads.  */
103   const int store;
104   const int strd;
105   const int stm_1st;
106   const int stm_regs_per_insn_1st;
107   const int stm_regs_per_insn_subsequent;
108   const int storef;		/* SFmode.  */
109   const int stored;		/* DFmode.  */
110   const int store_unaligned;	/* Extra for unaligned stores.  */
111   const int loadv;		/* Vector load.  */
112   const int storev;		/* Vector store.  */
113 };
114 
115 struct fp_cost_table
116 {
117   const int div;
118   const int mult;
119   const int mult_addsub;	/* Non-fused.  */
120   const int fma;		/* Fused.  */
121   const int addsub;
122   const int fpconst;		/* Immediate.  */
123   const int neg;		/* NEG and ABS.  */
124   const int compare;
125   const int widen;		/* Widen to this size.  */
126   const int narrow;		/* Narrow from this size.  */
127   const int toint;
128   const int fromint;
129   const int roundint;		/* V8 round to integral, remains FP format.  */
130 };
131 
132 struct vector_cost_table
133 {
134   const int alu;
135 };
136 
137 struct cpu_cost_table
138 {
139   const struct alu_cost_table alu;
140   const struct mult_cost_table mult[2]; /* SImode and DImode.  */
141   const struct mem_cost_table ldst;
142   const struct fp_cost_table fp[2]; /* SFmode and DFmode.  */
143   const struct vector_cost_table vect;
144 };
145 
146 rtx_insn *
147 arm_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &/*inputs*/,
148 		    vec<const char *> &constraints,
149 		    vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs);
150 
151 #endif /* GCC_AARCH_COMMON_PROTOS_H */
152