PR tree-optimization/84480 - bogus -Wstringop-truncation despite assignment with...
[official-gcc.git] / gcc / config / nds32 / nds32-cost.c
blob8d01e8afee253f3e97ad1981fabb91f38bb77813
1 /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #define IN_TARGET_CODE 1
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "memmodel.h"
33 #include "tm_p.h"
34 #include "optabs.h" /* For GEN_FCN. */
35 #include "recog.h"
36 #include "tm-constrs.h"
38 /* ------------------------------------------------------------------------ */
40 bool
41 nds32_rtx_costs_impl (rtx x,
42 machine_mode mode ATTRIBUTE_UNUSED,
43 int outer_code,
44 int opno ATTRIBUTE_UNUSED,
45 int *total,
46 bool speed)
48 int code = GET_CODE (x);
50 /* According to 'speed', goto suitable cost model section. */
51 if (speed)
52 goto performance_cost;
53 else
54 goto size_cost;
57 performance_cost:
58 /* This is section for performance cost model. */
60 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
61 We treat it as 4-cycle cost for each instruction
62 under performance consideration. */
63 switch (code)
65 case SET:
66 /* For 'SET' rtx, we need to return false
67 so that it can recursively calculate costs. */
68 return false;
70 case USE:
71 /* Used in combine.c as a marker. */
72 *total = 0;
73 break;
75 case MULT:
76 *total = COSTS_N_INSNS (1);
77 break;
79 case DIV:
80 case UDIV:
81 case MOD:
82 case UMOD:
83 *total = COSTS_N_INSNS (7);
84 break;
86 default:
87 *total = COSTS_N_INSNS (1);
88 break;
91 return true;
94 size_cost:
95 /* This is section for size cost model. */
97 /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
98 We treat it as 4-byte cost for each instruction
99 under code size consideration. */
100 switch (code)
102 case SET:
103 /* For 'SET' rtx, we need to return false
104 so that it can recursively calculate costs. */
105 return false;
107 case USE:
108 /* Used in combine.c as a marker. */
109 *total = 0;
110 break;
112 case CONST_INT:
113 /* All instructions involving constant operation
114 need to be considered for cost evaluation. */
115 if (outer_code == SET)
117 /* (set X imm5s), use movi55, 2-byte cost.
118 (set X imm20s), use movi, 4-byte cost.
119 (set X BIG_INT), use sethi/ori, 8-byte cost. */
120 if (satisfies_constraint_Is05 (x))
121 *total = COSTS_N_INSNS (1) - 2;
122 else if (satisfies_constraint_Is20 (x))
123 *total = COSTS_N_INSNS (1);
124 else
125 *total = COSTS_N_INSNS (2);
127 else if (outer_code == PLUS || outer_code == MINUS)
129 /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
130 General case, cost 1 instruction with 4-byte. */
131 if (satisfies_constraint_Iu05 (x))
132 *total = COSTS_N_INSNS (1) - 2;
133 else
134 *total = COSTS_N_INSNS (1);
136 else if (outer_code == ASHIFT)
138 /* Possible slli333, 2-byte cost.
139 General case, cost 1 instruction with 4-byte. */
140 if (satisfies_constraint_Iu03 (x))
141 *total = COSTS_N_INSNS (1) - 2;
142 else
143 *total = COSTS_N_INSNS (1);
145 else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
147 /* Possible srai45 or srli45, 2-byte cost.
148 General case, cost 1 instruction with 4-byte. */
149 if (satisfies_constraint_Iu05 (x))
150 *total = COSTS_N_INSNS (1) - 2;
151 else
152 *total = COSTS_N_INSNS (1);
154 else
156 /* For other cases, simply set it 4-byte cost. */
157 *total = COSTS_N_INSNS (1);
159 break;
161 case CONST_DOUBLE:
162 /* It requires high part and low part processing, set it 8-byte cost. */
163 *total = COSTS_N_INSNS (2);
164 break;
166 default:
167 /* For other cases, generally we set it 4-byte cost
168 and stop resurively traversing. */
169 *total = COSTS_N_INSNS (1);
170 break;
173 return true;
177 nds32_address_cost_impl (rtx address,
178 machine_mode mode ATTRIBUTE_UNUSED,
179 addr_space_t as ATTRIBUTE_UNUSED,
180 bool speed)
182 rtx plus0, plus1;
183 enum rtx_code code;
185 code = GET_CODE (address);
187 /* According to 'speed', goto suitable cost model section. */
188 if (speed)
189 goto performance_cost;
190 else
191 goto size_cost;
193 performance_cost:
194 /* This is section for performance cost model. */
196 /* FALLTHRU, currently we use same cost model as size_cost. */
198 size_cost:
199 /* This is section for size cost model. */
201 switch (code)
203 case POST_MODIFY:
204 case POST_INC:
205 case POST_DEC:
206 /* We encourage that rtx contains
207 POST_MODIFY/POST_INC/POST_DEC behavior. */
208 return 0;
210 case SYMBOL_REF:
211 /* We can have gp-relative load/store for symbol_ref.
212 Have it 4-byte cost. */
213 return COSTS_N_INSNS (1);
215 case CONST:
216 /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
217 Have it 4-byte cost. */
218 return COSTS_N_INSNS (1);
220 case REG:
221 /* Simply return 4-byte costs. */
222 return COSTS_N_INSNS (1);
224 case PLUS:
225 /* We do not need to check if the address is a legitimate address,
226 because this hook is never called with an invalid address.
227 But we better check the range of
228 const_int value for cost, if it exists. */
229 plus0 = XEXP (address, 0);
230 plus1 = XEXP (address, 1);
232 if (REG_P (plus0) && CONST_INT_P (plus1))
234 /* If it is possible to be lwi333/swi333 form,
235 make it 2-byte cost. */
236 if (satisfies_constraint_Iu05 (plus1))
237 return (COSTS_N_INSNS (1) - 2);
238 else
239 return COSTS_N_INSNS (1);
242 /* For other 'plus' situation, make it cost 4-byte. */
243 return COSTS_N_INSNS (1);
245 default:
246 break;
249 return COSTS_N_INSNS (4);
252 /* ------------------------------------------------------------------------ */