xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/nds32/nds32-cost.c (revision 5dd36a3bc8bf2a9dec29ceb6349550414570c447)
1 /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler
2    Copyright (C) 2012-2017 Free Software Foundation, Inc.
3    Contributed by Andes Technology Corporation.
4 
5    This file is part of GCC.
6 
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.
11 
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.
16 
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/>.  */
20 
21 /* ------------------------------------------------------------------------ */
22 
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "optabs.h"		/* For GEN_FCN.  */
33 #include "recog.h"
34 #include "tm-constrs.h"
35 
36 /* ------------------------------------------------------------------------ */
37 
38 bool
39 nds32_rtx_costs_impl (rtx x,
40 		      machine_mode mode ATTRIBUTE_UNUSED,
41 		      int outer_code,
42 		      int opno ATTRIBUTE_UNUSED,
43 		      int *total,
44 		      bool speed)
45 {
46   int code = GET_CODE (x);
47 
48   /* According to 'speed', goto suitable cost model section.  */
49   if (speed)
50     goto performance_cost;
51   else
52     goto size_cost;
53 
54 
55 performance_cost:
56   /* This is section for performance cost model.  */
57 
58   /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
59      We treat it as 4-cycle cost for each instruction
60      under performance consideration.  */
61   switch (code)
62     {
63     case SET:
64       /* For 'SET' rtx, we need to return false
65          so that it can recursively calculate costs.  */
66       return false;
67 
68     case USE:
69       /* Used in combine.c as a marker.  */
70       *total = 0;
71       break;
72 
73     case MULT:
74       *total = COSTS_N_INSNS (1);
75       break;
76 
77     case DIV:
78     case UDIV:
79     case MOD:
80     case UMOD:
81       *total = COSTS_N_INSNS (7);
82       break;
83 
84     default:
85       *total = COSTS_N_INSNS (1);
86       break;
87     }
88 
89   return true;
90 
91 
92 size_cost:
93   /* This is section for size cost model.  */
94 
95   /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
96      We treat it as 4-byte cost for each instruction
97      under code size consideration.  */
98   switch (code)
99     {
100     case SET:
101       /* For 'SET' rtx, we need to return false
102          so that it can recursively calculate costs.  */
103       return false;
104 
105     case USE:
106       /* Used in combine.c as a marker.  */
107       *total = 0;
108       break;
109 
110     case CONST_INT:
111       /* All instructions involving constant operation
112          need to be considered for cost evaluation.  */
113       if (outer_code == SET)
114 	{
115 	  /* (set X imm5s), use movi55, 2-byte cost.
116 	     (set X imm20s), use movi, 4-byte cost.
117 	     (set X BIG_INT), use sethi/ori, 8-byte cost.  */
118 	  if (satisfies_constraint_Is05 (x))
119 	    *total = COSTS_N_INSNS (1) - 2;
120 	  else if (satisfies_constraint_Is20 (x))
121 	    *total = COSTS_N_INSNS (1);
122 	  else
123 	    *total = COSTS_N_INSNS (2);
124 	}
125       else if (outer_code == PLUS || outer_code == MINUS)
126 	{
127 	  /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
128 	     General case, cost 1 instruction with 4-byte.  */
129 	  if (satisfies_constraint_Iu05 (x))
130 	    *total = COSTS_N_INSNS (1) - 2;
131 	  else
132 	    *total = COSTS_N_INSNS (1);
133 	}
134       else if (outer_code == ASHIFT)
135 	{
136 	  /* Possible slli333, 2-byte cost.
137 	     General case, cost 1 instruction with 4-byte.  */
138 	  if (satisfies_constraint_Iu03 (x))
139 	    *total = COSTS_N_INSNS (1) - 2;
140 	  else
141 	    *total = COSTS_N_INSNS (1);
142 	}
143       else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
144 	{
145 	  /* Possible srai45 or srli45, 2-byte cost.
146 	     General case, cost 1 instruction with 4-byte.  */
147 	  if (satisfies_constraint_Iu05 (x))
148 	    *total = COSTS_N_INSNS (1) - 2;
149 	  else
150 	    *total = COSTS_N_INSNS (1);
151 	}
152       else
153 	{
154 	  /* For other cases, simply set it 4-byte cost.  */
155 	  *total = COSTS_N_INSNS (1);
156 	}
157       break;
158 
159     case CONST_DOUBLE:
160       /* It requires high part and low part processing, set it 8-byte cost.  */
161       *total = COSTS_N_INSNS (2);
162       break;
163 
164     default:
165       /* For other cases, generally we set it 4-byte cost
166          and stop resurively traversing.  */
167       *total = COSTS_N_INSNS (1);
168       break;
169     }
170 
171   return true;
172 }
173 
174 int
175 nds32_address_cost_impl (rtx address,
176 			 machine_mode mode ATTRIBUTE_UNUSED,
177 			 addr_space_t as ATTRIBUTE_UNUSED,
178 			 bool speed)
179 {
180   rtx plus0, plus1;
181   enum rtx_code code;
182 
183   code = GET_CODE (address);
184 
185   /* According to 'speed', goto suitable cost model section.  */
186   if (speed)
187     goto performance_cost;
188   else
189     goto size_cost;
190 
191 performance_cost:
192   /* This is section for performance cost model.  */
193 
194   /* FALLTHRU, currently we use same cost model as size_cost.  */
195 
196 size_cost:
197   /* This is section for size cost model.  */
198 
199   switch (code)
200     {
201     case POST_MODIFY:
202     case POST_INC:
203     case POST_DEC:
204       /* We encourage that rtx contains
205          POST_MODIFY/POST_INC/POST_DEC behavior.  */
206       return 0;
207 
208     case SYMBOL_REF:
209       /* We can have gp-relative load/store for symbol_ref.
210          Have it 4-byte cost.  */
211       return COSTS_N_INSNS (1);
212 
213     case CONST:
214       /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
215          Have it 4-byte cost.  */
216       return COSTS_N_INSNS (1);
217 
218     case REG:
219       /* Simply return 4-byte costs.  */
220       return COSTS_N_INSNS (1);
221 
222     case PLUS:
223       /* We do not need to check if the address is a legitimate address,
224          because this hook is never called with an invalid address.
225          But we better check the range of
226          const_int value for cost, if it exists.  */
227       plus0 = XEXP (address, 0);
228       plus1 = XEXP (address, 1);
229 
230       if (REG_P (plus0) && CONST_INT_P (plus1))
231         {
232 	  /* If it is possible to be lwi333/swi333 form,
233 	     make it 2-byte cost.  */
234 	  if (satisfies_constraint_Iu05 (plus1))
235 	    return (COSTS_N_INSNS (1) - 2);
236 	  else
237 	    return COSTS_N_INSNS (1);
238 	}
239 
240       /* For other 'plus' situation, make it cost 4-byte.  */
241       return COSTS_N_INSNS (1);
242 
243     default:
244       break;
245     }
246 
247   return COSTS_N_INSNS (4);
248 }
249 
250 /* ------------------------------------------------------------------------ */
251