1 /* Subroutines used for calculate rtx costs of Andes NDS32 cpu for GNU compiler
2    Copyright (C) 2012-2021 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 #define IN_TARGET_CODE 1
24 
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"
37 #include "tree-pass.h"
38 
39 /* ------------------------------------------------------------------------ */
40 
41 typedef bool (*rtx_cost_func) (rtx, int, int, int, int*);
42 
43 struct rtx_cost_model_t {
44   rtx_cost_func speed_prefer;
45   rtx_cost_func size_prefer;
46 };
47 
48 static rtx_cost_model_t rtx_cost_model;
49 
50 static int insn_size_16bit; /* Initial at nds32_init_rtx_costs.  */
51 static const int insn_size_32bit = 4;
52 
53 static bool
nds32_rtx_costs_speed_prefer(rtx x ATTRIBUTE_UNUSED,int code,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total)54 nds32_rtx_costs_speed_prefer (rtx x ATTRIBUTE_UNUSED,
55 			      int code,
56 			      int outer_code ATTRIBUTE_UNUSED,
57 			      int opno ATTRIBUTE_UNUSED,
58 			      int *total)
59 {
60   rtx op0;
61   rtx op1;
62   machine_mode mode = GET_MODE (x);
63   /* Scale cost by mode size.  */
64   int cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
65 
66   switch (code)
67     {
68     case USE:
69       /* Used in combine.c as a marker.  */
70       *total = 0;
71       return true;
72 
73     case CONST_INT:
74       /* When not optimizing for size, we care more about the cost
75 	 of hot code, and hot code is often in a loop.  If a constant
76 	 operand needs to be forced into a register, we will often be
77 	 able to hoist the constant load out of the loop, so the load
78 	 should not contribute to the cost.  */
79       if (outer_code == SET || outer_code == PLUS)
80 	*total = satisfies_constraint_Is20 (x) ? 0 : 4;
81       else if (outer_code == AND || outer_code == IOR || outer_code == XOR
82 	       || outer_code == MINUS)
83 	*total = satisfies_constraint_Iu15 (x) ? 0 : 4;
84       else if (outer_code == ASHIFT || outer_code == ASHIFTRT
85 	       || outer_code == LSHIFTRT)
86 	*total = satisfies_constraint_Iu05 (x) ? 0 : 4;
87       else if (GET_RTX_CLASS (outer_code) == RTX_COMPARE
88 	       || GET_RTX_CLASS (outer_code) == RTX_COMM_COMPARE)
89 	*total = satisfies_constraint_Is16 (x) ? 0 : 4;
90       else
91 	*total = COSTS_N_INSNS (1);
92       return true;
93 
94     case CONST:
95     case LO_SUM:
96     case HIGH:
97     case SYMBOL_REF:
98       *total = COSTS_N_INSNS (1);
99       return true;
100 
101     case MEM:
102       *total = COSTS_N_INSNS (1);
103       return true;
104 
105     case SET:
106       op0 = SET_DEST (x);
107       op1 = SET_SRC (x);
108       mode = GET_MODE (op0);
109       /* Scale cost by mode size.  */
110       cost = COSTS_N_INSNS (GET_MODE_SIZE (mode) / GET_MODE_SIZE (SImode));
111 
112       switch (GET_CODE (op1))
113 	{
114 	case REG:
115 	case SUBREG:
116 	  /* Register move and Store instructions.  */
117 	  if ((REG_P (op0) || MEM_P (op0))
118 	      && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
119 	    *total = COSTS_N_INSNS (1);
120 	  else
121 	    *total = cost;
122 	  return true;
123 
124 	case MEM:
125 	  /* Load instructions.  */
126 	  if (REG_P (op0) && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (DImode))
127 	    *total = COSTS_N_INSNS (1);
128 	  else
129 	    *total = cost;
130 	  return true;
131 
132 	case CONST_INT:
133 	  /* movi instruction.  */
134 	  if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
135 	    {
136 	      if (satisfies_constraint_Is20 (op1))
137 		*total = COSTS_N_INSNS (1) - 1;
138 	      else
139 		*total = COSTS_N_INSNS (2);
140 	    }
141 	  else
142 	    *total = cost;
143 	  return true;
144 
145 	case CONST:
146 	case SYMBOL_REF:
147 	case LABEL_REF:
148 	  /* la instruction.  */
149 	  if (REG_P (op0) && GET_MODE_SIZE (mode) < GET_MODE_SIZE (DImode))
150 	    *total = COSTS_N_INSNS (1) - 1;
151 	  else
152 	    *total = cost;
153 	  return true;
154 	case VEC_SELECT:
155 	  *total = cost;
156 	  return true;
157 
158 	default:
159 	  *total = cost;
160 	  return true;
161 	}
162 
163     case PLUS:
164       op0 = XEXP (x, 0);
165       op1 = XEXP (x, 1);
166 
167       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
168 	*total = cost;
169       else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
170 	       || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
171 	/* ALU_SHIFT */
172 	*total = COSTS_N_INSNS (2);
173 
174       else if ((GET_CODE (op1) == CONST_INT
175 		&& satisfies_constraint_Is15 (op1))
176 		|| REG_P (op1))
177 	/* ADD instructions */
178 	*total = COSTS_N_INSNS (1);
179       else
180 	/* ADD instructions: IMM out of range.  */
181 	*total = COSTS_N_INSNS (2);
182       return true;
183 
184     case MINUS:
185       op0 = XEXP (x, 0);
186       op1 = XEXP (x, 1);
187 
188       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
189 	*total = cost;
190       else if (GET_CODE (op0) == MULT || GET_CODE (op0) == LSHIFTRT
191 	       || GET_CODE (op1) == MULT || GET_CODE (op1) == LSHIFTRT)
192 	/* ALU_SHIFT */
193 	*total = COSTS_N_INSNS (2);
194       else if ((GET_CODE (op0) == CONST_INT
195 		&& satisfies_constraint_Is15 (op0))
196 		|| REG_P (op0))
197 	/* SUB instructions */
198 	*total = COSTS_N_INSNS (1);
199       else
200 	/* SUB instructions: IMM out of range.  */
201 	*total = COSTS_N_INSNS (2);
202       return true;
203 
204     case TRUNCATE:
205       /* TRUNCATE and AND behavior is same. */
206       *total = COSTS_N_INSNS (1);
207       return true;
208 
209     case AND:
210     case IOR:
211     case XOR:
212       op0 = XEXP (x, 0);
213       op1 = XEXP (x, 1);
214 
215       if (NDS32_EXT_DSP_P ())
216 	{
217 	  /* We prefer (and (ior) (ior)) than (ior (and) (and)) for
218 	     synthetize pk** and insb instruction.  */
219 	  if (code == AND && GET_CODE (op0) == IOR && GET_CODE (op1) == IOR)
220 	    return COSTS_N_INSNS (1);
221 
222 	  if (code == IOR && GET_CODE (op0) == AND && GET_CODE (op1) == AND)
223 	    return COSTS_N_INSNS (10);
224 	}
225 
226       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
227 	*total = cost;
228       else if (GET_CODE (op0) == ASHIFT || GET_CODE (op0) == LSHIFTRT)
229 	*total = COSTS_N_INSNS (2);
230       else if ((GET_CODE (op1) == CONST_INT
231 	       && satisfies_constraint_Iu15 (op1))
232 	       || REG_P (op1))
233 	/* AND, OR, XOR instructions */
234 	*total = COSTS_N_INSNS (1);
235       else if (code == AND || GET_CODE (op0) == NOT)
236 	/* BITC instruction */
237 	*total = COSTS_N_INSNS (1);
238       else
239 	/* AND, OR, XOR instructions: IMM out of range.  */
240 	*total = COSTS_N_INSNS (2);
241       return true;
242 
243     case MULT:
244       if (GET_MODE (x) == DImode
245 	  || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
246 	  || GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
247 	/* MUL instructions */
248 	*total = COSTS_N_INSNS (1);
249       else if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
250 	*total = cost;
251       else if (outer_code == PLUS || outer_code == MINUS)
252 	*total = COSTS_N_INSNS (2);
253       else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
254 	       && satisfies_constraint_Iu05 (XEXP (x, 1)))
255 	       || REG_P (XEXP (x, 1)))
256 	/* MUL instructions */
257 	*total = COSTS_N_INSNS (1);
258       else
259 	/* MUL instructions: IMM out of range.  */
260 	*total = COSTS_N_INSNS (2);
261 
262       if (TARGET_MUL_SLOW)
263 	*total += COSTS_N_INSNS (4);
264 
265       return true;
266 
267     case LSHIFTRT:
268       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
269 	*total = cost;
270       else if (outer_code == PLUS || outer_code == MINUS
271 	       || outer_code == AND || outer_code == IOR
272 	       || outer_code == XOR)
273 	*total = COSTS_N_INSNS (2);
274       else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
275 	       && satisfies_constraint_Iu05 (XEXP (x, 1)))
276 	       || REG_P (XEXP (x, 1)))
277 	/* SRL instructions */
278 	*total = COSTS_N_INSNS (1);
279       else
280 	/* SRL instructions: IMM out of range.  */
281 	*total = COSTS_N_INSNS (2);
282       return true;
283 
284     case ASHIFT:
285       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
286 	*total = cost;
287       else if (outer_code == AND || outer_code == IOR
288 	       || outer_code == XOR)
289 	*total = COSTS_N_INSNS (2);
290       else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
291 	       && satisfies_constraint_Iu05 (XEXP (x, 1)))
292 	       || REG_P (XEXP (x, 1)))
293 	/* SLL instructions */
294 	*total = COSTS_N_INSNS (1);
295       else
296 	/* SLL instructions: IMM out of range.  */
297 	*total = COSTS_N_INSNS (2);
298       return true;
299 
300     case ASHIFTRT:
301     case ROTATERT:
302       if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (DImode))
303 	*total = cost;
304       else if ((GET_CODE (XEXP (x, 1)) == CONST_INT
305 	       && satisfies_constraint_Iu05 (XEXP (x, 1)))
306 	       || REG_P (XEXP (x, 1)))
307 	/* ROTR, SLL instructions */
308 	*total = COSTS_N_INSNS (1);
309       else
310 	/* ROTR, SLL instructions: IMM out of range.  */
311 	*total = COSTS_N_INSNS (2);
312       return true;
313 
314     case LT:
315     case LTU:
316       if (outer_code == SET)
317 	{
318 	  if ((GET_CODE (XEXP (x, 1)) == CONST_INT
319 	      && satisfies_constraint_Iu15 (XEXP (x, 1)))
320 	      || REG_P (XEXP (x, 1)))
321 	    /* SLT, SLTI instructions */
322 	    *total = COSTS_N_INSNS (1);
323 	  else
324 	    /* SLT, SLT instructions: IMM out of range.  */
325 	    *total = COSTS_N_INSNS (2);
326 	}
327       else
328 	/* branch */
329 	*total = COSTS_N_INSNS (2);
330       return true;
331 
332     case EQ:
333     case NE:
334     case GE:
335     case LE:
336     case GT:
337       /* branch */
338       *total = COSTS_N_INSNS (2);
339       return true;
340 
341     case IF_THEN_ELSE:
342       if (GET_CODE (XEXP (x, 1)) == LABEL_REF)
343 	/* branch */
344 	*total = COSTS_N_INSNS (2);
345       else
346 	/* cmovz, cmovn instructions */
347 	*total = COSTS_N_INSNS (1);
348       return true;
349 
350     case LABEL_REF:
351       if (outer_code == IF_THEN_ELSE)
352 	/* branch */
353 	*total = COSTS_N_INSNS (2);
354       else
355 	*total = COSTS_N_INSNS (1);
356       return true;
357 
358     case ZERO_EXTEND:
359     case SIGN_EXTEND:
360       if (MEM_P (XEXP (x, 0)))
361 	/* Using memory access. */
362 	*total = COSTS_N_INSNS (1);
363       else
364 	/* Zero extend and sign extend instructions.  */
365 	*total = COSTS_N_INSNS (1);
366       return true;
367 
368     case NEG:
369     case NOT:
370       *total = COSTS_N_INSNS (1);
371       return true;
372 
373     case DIV:
374     case UDIV:
375     case MOD:
376     case UMOD:
377       *total = COSTS_N_INSNS (20);
378       return true;
379 
380     case CALL:
381       *total = COSTS_N_INSNS (2);
382       return true;
383 
384     case CLZ:
385     case SMIN:
386     case SMAX:
387     case ZERO_EXTRACT:
388       if (TARGET_EXT_PERF)
389 	*total = COSTS_N_INSNS (1);
390       else
391 	*total = COSTS_N_INSNS (3);
392       return true;
393     case VEC_SELECT:
394       *total = COSTS_N_INSNS (1);
395       return true;
396 
397     default:
398       *total = COSTS_N_INSNS (3);
399       return true;
400     }
401 }
402 
403 static bool
nds32_rtx_costs_size_prefer(rtx x,int code,int outer_code,int opno ATTRIBUTE_UNUSED,int * total)404 nds32_rtx_costs_size_prefer (rtx x,
405 			     int code,
406 			     int outer_code,
407 			     int opno ATTRIBUTE_UNUSED,
408 			     int *total)
409 {
410   /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
411      We treat it as 4-byte cost for each instruction
412      under code size consideration.  */
413   switch (code)
414     {
415     case SET:
416       /* For 'SET' rtx, we need to return false
417 	 so that it can recursively calculate costs.  */
418       return false;
419 
420     case USE:
421       /* Used in combine.c as a marker.  */
422       *total = 0;
423       break;
424 
425     case CONST_INT:
426       /* All instructions involving constant operation
427 	 need to be considered for cost evaluation.  */
428       if (outer_code == SET)
429 	{
430 	  /* (set X imm5s), use movi55, 2-byte cost.
431 	     (set X imm20s), use movi, 4-byte cost.
432 	     (set X BIG_INT), use sethi/ori, 8-byte cost.  */
433 	  if (satisfies_constraint_Is05 (x))
434 	    *total = insn_size_16bit;
435 	  else if (satisfies_constraint_Is20 (x))
436 	    *total = insn_size_32bit;
437 	  else
438 	    *total = insn_size_32bit * 2;
439 	}
440       else if (outer_code == PLUS || outer_code == MINUS)
441 	{
442 	  /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
443 	     General case, cost 1 instruction with 4-byte.  */
444 	  if (satisfies_constraint_Iu05 (x))
445 	    *total = insn_size_16bit;
446 	  else
447 	    *total = insn_size_32bit;
448 	}
449       else if (outer_code == ASHIFT)
450 	{
451 	  /* Possible slli333, 2-byte cost.
452 	     General case, cost 1 instruction with 4-byte.  */
453 	  if (satisfies_constraint_Iu03 (x))
454 	    *total = insn_size_16bit;
455 	  else
456 	    *total = insn_size_32bit;
457 	}
458       else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
459 	{
460 	  /* Possible srai45 or srli45, 2-byte cost.
461 	     General case, cost 1 instruction with 4-byte.  */
462 	  if (satisfies_constraint_Iu05 (x))
463 	    *total = insn_size_16bit;
464 	  else
465 	    *total = insn_size_32bit;
466 	}
467       else
468 	{
469 	  /* For other cases, simply set it 4-byte cost.  */
470 	  *total = insn_size_32bit;
471 	}
472       break;
473 
474     case CONST_DOUBLE:
475       /* It requires high part and low part processing, set it 8-byte cost.  */
476       *total = insn_size_32bit * 2;
477       break;
478 
479     case CONST:
480     case SYMBOL_REF:
481       *total = insn_size_32bit * 2;
482       break;
483 
484     default:
485       /* For other cases, generally we set it 4-byte cost
486 	 and stop resurively traversing.  */
487       *total = insn_size_32bit;
488       break;
489     }
490 
491   return true;
492 }
493 
494 void
nds32_init_rtx_costs(void)495 nds32_init_rtx_costs (void)
496 {
497   rtx_cost_model.speed_prefer = nds32_rtx_costs_speed_prefer;
498   rtx_cost_model.size_prefer  = nds32_rtx_costs_size_prefer;
499 
500   if (TARGET_16_BIT)
501     insn_size_16bit = 2;
502   else
503     insn_size_16bit = 4;
504 }
505 
506 /* This target hook describes the relative costs of RTL expressions.
507    Return 'true' when all subexpressions of x have been processed.
508    Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
509    Refer to gcc/rtlanal.c for more information.  */
510 bool
nds32_rtx_costs_impl(rtx x,machine_mode mode ATTRIBUTE_UNUSED,int outer_code,int opno,int * total,bool speed)511 nds32_rtx_costs_impl (rtx x,
512 		      machine_mode mode ATTRIBUTE_UNUSED,
513 		      int outer_code,
514 		      int opno,
515 		      int *total,
516 		      bool speed)
517 {
518   int code = GET_CODE (x);
519 
520   /* According to 'speed', use suitable cost model section.  */
521   if (speed)
522     return rtx_cost_model.speed_prefer(x, code, outer_code, opno, total);
523   else
524     return rtx_cost_model.size_prefer(x, code, outer_code, opno, total);
525 }
526 
527 
nds32_address_cost_speed_prefer(rtx address)528 int nds32_address_cost_speed_prefer (rtx address)
529 {
530   rtx plus0, plus1;
531   enum rtx_code code;
532 
533   code = GET_CODE (address);
534 
535   switch (code)
536     {
537     case POST_MODIFY:
538     case POST_INC:
539     case POST_DEC:
540       /* We encourage that rtx contains
541 	 POST_MODIFY/POST_INC/POST_DEC behavior.  */
542       return COSTS_N_INSNS (1) - 2;
543 
544     case SYMBOL_REF:
545       /* We can have gp-relative load/store for symbol_ref.
546 	Have it 4-byte cost.  */
547       return COSTS_N_INSNS (2);
548 
549     case CONST:
550       /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
551 	 Have it 4-byte cost.  */
552       return COSTS_N_INSNS (2);
553 
554     case REG:
555       /* Simply return 4-byte costs.  */
556       return COSTS_N_INSNS (1) - 2;
557 
558     case PLUS:
559       /* We do not need to check if the address is a legitimate address,
560 	 because this hook is never called with an invalid address.
561 	 But we better check the range of
562 	 const_int value for cost, if it exists.  */
563       plus0 = XEXP (address, 0);
564       plus1 = XEXP (address, 1);
565 
566       if (REG_P (plus0) && CONST_INT_P (plus1))
567 	return COSTS_N_INSNS (1) - 2;
568       else if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
569 	return COSTS_N_INSNS (1) - 1;
570       else if (REG_P (plus0) && REG_P (plus1))
571 	return COSTS_N_INSNS (1);
572 
573       /* For other 'plus' situation, make it cost 4-byte.  */
574       return COSTS_N_INSNS (1);
575 
576     default:
577       break;
578     }
579 
580   return COSTS_N_INSNS (4);
581 
582 }
583 
nds32_address_cost_speed_fwprop(rtx address)584 int nds32_address_cost_speed_fwprop (rtx address)
585 {
586   rtx plus0, plus1;
587   enum rtx_code code;
588 
589   code = GET_CODE (address);
590 
591   switch (code)
592     {
593     case POST_MODIFY:
594     case POST_INC:
595     case POST_DEC:
596       /* We encourage that rtx contains
597 	 POST_MODIFY/POST_INC/POST_DEC behavior.  */
598       return 0;
599 
600     case SYMBOL_REF:
601       /* We can have gp-relative load/store for symbol_ref.
602 	 Have it 4-byte cost.  */
603       return COSTS_N_INSNS (2);
604 
605     case CONST:
606       /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
607 	 Have it 4-byte cost.  */
608       return COSTS_N_INSNS (2);
609 
610     case REG:
611       /* Simply return 4-byte costs.  */
612       return COSTS_N_INSNS (1);
613 
614     case PLUS:
615       /* We do not need to check if the address is a legitimate address,
616 	 because this hook is never called with an invalid address.
617 	 But we better check the range of
618 	 const_int value for cost, if it exists.  */
619       plus0 = XEXP (address, 0);
620       plus1 = XEXP (address, 1);
621 
622       if (REG_P (plus0) && CONST_INT_P (plus1))
623 	{
624 	  /* If it is possible to be lwi333/swi333 form,
625 	     make it 2-byte cost.  */
626 	  if (satisfies_constraint_Iu03 (plus1))
627 	    return (COSTS_N_INSNS (1) - 2);
628 	  else
629 	    return COSTS_N_INSNS (1);
630 	}
631       if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
632 	return COSTS_N_INSNS (1) - 2;
633       else if (REG_P (plus0) && REG_P (plus1))
634 	return COSTS_N_INSNS (1);
635 
636       /* For other 'plus' situation, make it cost 4-byte.  */
637       return COSTS_N_INSNS (1);
638 
639     default:
640       break;
641     }
642 
643   return COSTS_N_INSNS (4);
644 }
645 
646 
nds32_address_cost_size_prefer(rtx address)647 int nds32_address_cost_size_prefer (rtx address)
648 {
649   rtx plus0, plus1;
650   enum rtx_code code;
651 
652   code = GET_CODE (address);
653 
654   switch (code)
655     {
656     case POST_MODIFY:
657     case POST_INC:
658     case POST_DEC:
659       /* We encourage that rtx contains
660 	 POST_MODIFY/POST_INC/POST_DEC behavior.  */
661       return 0;
662 
663     case SYMBOL_REF:
664       /* We can have gp-relative load/store for symbol_ref.
665 	 Have it 4-byte cost.  */
666       return COSTS_N_INSNS (2);
667 
668     case CONST:
669       /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
670 	 Have it 4-byte cost.  */
671       return COSTS_N_INSNS (2);
672 
673     case REG:
674       /* Simply return 4-byte costs.  */
675       return COSTS_N_INSNS (1) - 1;
676 
677     case PLUS:
678       /* We do not need to check if the address is a legitimate address,
679 	 because this hook is never called with an invalid address.
680 	 But we better check the range of
681 	 const_int value for cost, if it exists.  */
682       plus0 = XEXP (address, 0);
683       plus1 = XEXP (address, 1);
684 
685       if (REG_P (plus0) && CONST_INT_P (plus1))
686 	{
687 	  /* If it is possible to be lwi333/swi333 form,
688 	     make it 2-byte cost.  */
689 	  if (satisfies_constraint_Iu03 (plus1))
690 	    return (COSTS_N_INSNS (1) - 2);
691 	  else
692 	    return COSTS_N_INSNS (1) - 1;
693 	}
694 
695       /* (plus (reg) (mult (reg) (const))) */
696       if (ARITHMETIC_P (plus0) || ARITHMETIC_P (plus1))
697 	return (COSTS_N_INSNS (1) - 1);
698 
699       /* For other 'plus' situation, make it cost 4-byte.  */
700       return COSTS_N_INSNS (1);
701 
702     default:
703       break;
704     }
705 
706   return COSTS_N_INSNS (4);
707 
708 }
709 
nds32_address_cost_impl(rtx address,machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed_p)710 int nds32_address_cost_impl (rtx address,
711 			     machine_mode mode ATTRIBUTE_UNUSED,
712 			     addr_space_t as ATTRIBUTE_UNUSED,
713 			     bool speed_p)
714 {
715   if (speed_p)
716     {
717       if (current_pass->tv_id == TV_FWPROP)
718 	return nds32_address_cost_speed_fwprop (address);
719       else
720 	return nds32_address_cost_speed_prefer (address);
721     }
722   else
723     return nds32_address_cost_size_prefer (address);
724 }
725 
726 /* ------------------------------------------------------------------------ */
727