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