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