1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2    Copyright (C) 2012-2014 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 "tm.h"
27 #include "tree.h"
28 #include "stor-layout.h"
29 #include "varasm.h"
30 #include "calls.h"
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h"	/* Required by recog.h.  */
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"		/* For DFA state_t.  */
38 #include "insn-codes.h"		/* For CODE_FOR_xxx.  */
39 #include "reload.h"		/* For push_reload().  */
40 #include "flags.h"
41 #include "function.h"
42 #include "expr.h"
43 #include "recog.h"
44 #include "diagnostic-core.h"
45 #include "df.h"
46 #include "tm_p.h"
47 #include "tm-constrs.h"
48 #include "optabs.h"		/* For GEN_FCN.  */
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h"		/* For add_builtin_function().  */
52 #include "ggc.h"
53 
54 /* ------------------------------------------------------------------------ */
55 
56 /* This file is divided into five parts:
57 
58      PART 1: Auxiliary static variable definitions and
59              target hook static variable definitions.
60 
61      PART 2: Auxiliary static function definitions.
62 
63      PART 3: Implement target hook stuff definitions.
64 
65      PART 4: Implemet extern function definitions,
66              the prototype is in nds32-protos.h.
67 
68      PART 5: Initialize target hook structure and definitions.  */
69 
70 /* ------------------------------------------------------------------------ */
71 
72 /* PART 1: Auxiliary static variable definitions and
73            target hook static variable definitions.  */
74 
75 /* Refer to nds32.h, there are maximum 73 isr vectors in nds32 architecture.
76    0 for reset handler with __attribute__((reset())),
77    1-8 for exception handler with __attribute__((exception(1,...,8))),
78    and 9-72 for interrupt handler with __attribute__((interrupt(0,...,63))).
79    We use an array to record essential information for each vector.  */
80 static struct nds32_isr_info nds32_isr_vectors[NDS32_N_ISR_VECTORS];
81 
82 /* Define intrinsic register names.
83    Please refer to nds32_intrinsic.h file, the index is corresponding to
84    'enum nds32_intrinsic_registers' data type values.
85    NOTE that the base value starting from 1024.  */
86 static const char * const nds32_intrinsic_register_names[] =
87 {
88   "$PSW", "$IPSW", "$ITYPE", "$IPC"
89 };
90 
91 /* Defining target-specific uses of __attribute__.  */
92 static const struct attribute_spec nds32_attribute_table[] =
93 {
94   /* Syntax: { name, min_len, max_len, decl_required, type_required,
95                function_type_required, handler, affects_type_identity } */
96 
97   /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72).  */
98   { "interrupt",    1, 64, false, false, false, NULL, false },
99   /* The exception vid: [1-8]+  (actual vector number starts from 1 to 8).  */
100   { "exception",    1,  8, false, false, false, NULL, false },
101   /* Argument is user's interrupt numbers.  The vector number is always 0.  */
102   { "reset",        1,  1, false, false, false, NULL, false },
103 
104   /* The attributes describing isr nested type.  */
105   { "nested",       0,  0, false, false, false, NULL, false },
106   { "not_nested",   0,  0, false, false, false, NULL, false },
107   { "nested_ready", 0,  0, false, false, false, NULL, false },
108 
109   /* The attributes describing isr register save scheme.  */
110   { "save_all",     0,  0, false, false, false, NULL, false },
111   { "partial_save", 0,  0, false, false, false, NULL, false },
112 
113   /* The attributes used by reset attribute.  */
114   { "nmi",          1,  1, false, false, false, NULL, false },
115   { "warm",         1,  1, false, false, false, NULL, false },
116 
117   /* The attribute telling no prologue/epilogue.  */
118   { "naked",        0,  0, false, false, false, NULL, false },
119 
120   /* The last attribute spec is set to be NULL.  */
121   { NULL,           0,  0, false, false, false, NULL, false }
122 };
123 
124 
125 /* ------------------------------------------------------------------------ */
126 
127 /* PART 2: Auxiliary static function definitions.  */
128 
129 /* Function to save and restore machine-specific function data.  */
130 static struct machine_function *
nds32_init_machine_status(void)131 nds32_init_machine_status (void)
132 {
133   struct machine_function *machine;
134   machine = ggc_alloc_cleared_machine_function ();
135 
136   /* Initially assume this function needs prologue/epilogue.  */
137   machine->naked_p = 0;
138 
139   /* Initially assume this function does NOT use fp_as_gp optimization.  */
140   machine->fp_as_gp_p = 0;
141 
142   return machine;
143 }
144 
145 /* Function to compute stack frame size and
146    store into cfun->machine structure.  */
147 static void
nds32_compute_stack_frame(void)148 nds32_compute_stack_frame (void)
149 {
150   int r;
151   int block_size;
152 
153   /* Because nds32_compute_stack_frame() will be called from different place,
154      everytime we enter this function, we have to assume this function
155      needs prologue/epilogue.  */
156   cfun->machine->naked_p = 0;
157 
158   /* Get variadic arguments size to prepare pretend arguments and
159      push them into stack at prologue.
160      Currently, we do not push variadic arguments by ourself.
161      We have GCC handle all the works.
162      The caller will push all corresponding nameless arguments into stack,
163      and the callee is able to retrieve them without problems.
164      These variables are still preserved in case one day
165      we would like caller passing arguments with registers.  */
166   cfun->machine->va_args_size = 0;
167   cfun->machine->va_args_first_regno = SP_REGNUM;
168   cfun->machine->va_args_last_regno  = SP_REGNUM;
169 
170   /* Get local variables, incoming variables, and temporary variables size.
171      Note that we need to make sure it is 8-byte alignment because
172      there may be no padding bytes if we are using LRA.  */
173   cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
174 
175   /* Get outgoing arguments size.  */
176   cfun->machine->out_args_size = crtl->outgoing_args_size;
177 
178   /* If $fp value is required to be saved on stack, it needs 4 bytes space.
179      Check whether $fp is ever live.  */
180   cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
181 
182   /* If $gp value is required to be saved on stack, it needs 4 bytes space.
183      Check whether we are using PIC code genration.  */
184   cfun->machine->gp_size = (flag_pic) ? 4 : 0;
185 
186   /* If $lp value is required to be saved on stack, it needs 4 bytes space.
187      Check whether $lp is ever live.  */
188   cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
189 
190   /* Initially there is no padding bytes.  */
191   cfun->machine->callee_saved_area_padding_bytes = 0;
192 
193   /* Calculate the bytes of saving callee-saved registers on stack.  */
194   cfun->machine->callee_saved_regs_size = 0;
195   cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
196   cfun->machine->callee_saved_regs_last_regno  = SP_REGNUM;
197   /* Currently, there is no need to check $r28~$r31
198      because we will save them in another way.  */
199   for (r = 0; r < 28; r++)
200     {
201       if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
202 	{
203 	  /* Mark the first required callee-saved register
204 	     (only need to set it once).
205 	     If first regno == SP_REGNUM, we can tell that
206 	     it is the first time to be here.  */
207 	  if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
208 	    cfun->machine->callee_saved_regs_first_regno = r;
209 	  /* Mark the last required callee-saved register.  */
210 	  cfun->machine->callee_saved_regs_last_regno = r;
211 	}
212     }
213 
214   /* Check if this function can omit prologue/epilogue code fragment.
215      If there is 'naked' attribute in this function,
216      we can set 'naked_p' flag to indicate that
217      we do not have to generate prologue/epilogue.
218      Or, if all the following conditions succeed,
219      we can set this function 'naked_p' as well:
220        condition 1: first_regno == last_regno == SP_REGNUM,
221                     which means we do not have to save
222                     any callee-saved registers.
223        condition 2: Both $lp and $fp are NOT live in this function,
224                     which means we do not need to save them.
225        condition 3: There is no local_size, which means
226                     we do not need to adjust $sp.  */
227   if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
228       || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
229 	  && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
230 	  && !df_regs_ever_live_p (FP_REGNUM)
231 	  && !df_regs_ever_live_p (LP_REGNUM)
232 	  && cfun->machine->local_size == 0))
233     {
234       /* Set this function 'naked_p' and
235          other functions can check this flag.  */
236       cfun->machine->naked_p = 1;
237 
238       /* No need to save $fp, $gp, and $lp.
239          We should set these value to be zero
240          so that nds32_initial_elimination_offset() can work properly.  */
241       cfun->machine->fp_size = 0;
242       cfun->machine->gp_size = 0;
243       cfun->machine->lp_size = 0;
244 
245       /* If stack usage computation is required,
246          we need to provide the static stack size.  */
247       if (flag_stack_usage_info)
248 	current_function_static_stack_size = 0;
249 
250       /* No need to do following adjustment, return immediately.  */
251       return;
252     }
253 
254   /* Adjustment for v3push instructions:
255      If we are using v3push (push25/pop25) instructions,
256      we need to make sure Rb is $r6 and Re is
257      located on $r6, $r8, $r10, or $r14.
258      Some results above will be discarded and recomputed.
259      Note that it is only available under V3/V3M ISA.  */
260   if (TARGET_V3PUSH)
261     {
262       /* Recompute:
263            cfun->machine->fp_size
264            cfun->machine->gp_size
265            cfun->machine->lp_size
266            cfun->machine->callee_saved_regs_first_regno
267            cfun->machine->callee_saved_regs_last_regno */
268 
269       /* For v3push instructions, $fp, $gp, and $lp are always saved.  */
270       cfun->machine->fp_size = 4;
271       cfun->machine->gp_size = 4;
272       cfun->machine->lp_size = 4;
273 
274       /* Remember to set Rb = $r6.  */
275       cfun->machine->callee_saved_regs_first_regno = 6;
276 
277       if (cfun->machine->callee_saved_regs_last_regno <= 6)
278 	{
279 	  /* Re = $r6 */
280 	  cfun->machine->callee_saved_regs_last_regno = 6;
281 	}
282       else if (cfun->machine->callee_saved_regs_last_regno <= 8)
283 	{
284 	  /* Re = $r8 */
285 	  cfun->machine->callee_saved_regs_last_regno = 8;
286 	}
287       else if (cfun->machine->callee_saved_regs_last_regno <= 10)
288 	{
289 	  /* Re = $r10 */
290 	  cfun->machine->callee_saved_regs_last_regno = 10;
291 	}
292       else if (cfun->machine->callee_saved_regs_last_regno <= 14)
293 	{
294 	  /* Re = $r14 */
295 	  cfun->machine->callee_saved_regs_last_regno = 14;
296 	}
297       else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
298 	{
299 	  /* If last_regno is SP_REGNUM, which means
300 	     it is never changed, so set it to Re = $r6.  */
301 	  cfun->machine->callee_saved_regs_last_regno = 6;
302 	}
303       else
304 	{
305 	  /* The program flow should not go here.  */
306 	  gcc_unreachable ();
307 	}
308     }
309 
310   /* We have correctly set callee_saved_regs_first_regno
311      and callee_saved_regs_last_regno.
312      Initially, the callee_saved_regs_size is supposed to be 0.
313      As long as callee_saved_regs_last_regno is not SP_REGNUM,
314      we can update callee_saved_regs_size with new size.  */
315   if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
316     {
317       /* Compute pushed size of callee-saved registers.  */
318       cfun->machine->callee_saved_regs_size
319 	= 4 * (cfun->machine->callee_saved_regs_last_regno
320 	       - cfun->machine->callee_saved_regs_first_regno
321 	       + 1);
322     }
323 
324   /* Important: We need to make sure that
325                 (va_args_size + fp_size + gp_size
326                  + lp_size + callee_saved_regs_size)
327                 is 8-byte alignment.
328                 If it is not, calculate the padding bytes.  */
329   block_size = cfun->machine->va_args_size
330 	       + cfun->machine->fp_size
331 	       + cfun->machine->gp_size
332 	       + cfun->machine->lp_size
333 	       + cfun->machine->callee_saved_regs_size;
334   if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
335     {
336       cfun->machine->callee_saved_area_padding_bytes
337 	= NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
338     }
339 
340   /* If stack usage computation is required,
341      we need to provide the static stack size.  */
342   if (flag_stack_usage_info)
343     {
344       current_function_static_stack_size
345 	= NDS32_ROUND_UP_DOUBLE_WORD (block_size)
346 	  + cfun->machine->local_size
347 	  + cfun->machine->out_args_size;
348     }
349 }
350 
351 /* Function to create a parallel rtx pattern
352    which presents stack push multiple behavior.
353    The overall concept are:
354      "push registers to memory",
355      "adjust stack pointer".  */
356 static rtx
nds32_gen_stack_push_multiple(rtx Rb,rtx Re,rtx En4 ATTRIBUTE_UNUSED)357 nds32_gen_stack_push_multiple (rtx Rb, rtx Re,
358 			       rtx En4 ATTRIBUTE_UNUSED)
359 {
360   int regno;
361   int extra_count;
362   int num_use_regs;
363   int par_index;
364   int offset;
365 
366   rtx reg;
367   rtx mem;
368   rtx push_rtx;
369   rtx adjust_sp_rtx;
370   rtx parallel_insn;
371 
372   /* We need to provide a customized rtx which contains
373      necessary information for data analysis,
374      so we create a parallel rtx like this:
375      (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
376                      (reg:SI Rb))
377                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
378                      (reg:SI Rb+1))
379                 ...
380                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
381                      (reg:SI Re))
382                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
383                      (reg:SI FP_REGNUM))
384                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
385                      (reg:SI GP_REGNUM))
386                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
387                      (reg:SI LP_REGNUM))
388                 (set (reg:SI SP_REGNUM)
389                      (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
390 
391   /* Calculate the number of registers that will be pushed.  */
392   extra_count = 0;
393   if (cfun->machine->fp_size)
394     extra_count++;
395   if (cfun->machine->gp_size)
396     extra_count++;
397   if (cfun->machine->lp_size)
398     extra_count++;
399   /* Note that Rb and Re may be SP_REGNUM.  DO NOT count it in.  */
400   if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
401     num_use_regs = extra_count;
402   else
403     num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
404 
405   /* In addition to used registers,
406      we need one more space for (set sp sp-x) rtx.  */
407   parallel_insn = gen_rtx_PARALLEL (VOIDmode,
408 				    rtvec_alloc (num_use_regs + 1));
409   par_index = 0;
410 
411   /* Initialize offset and start to create push behavior.  */
412   offset = -(num_use_regs * 4);
413 
414   /* Create (set mem regX) from Rb, Rb+1 up to Re.  */
415   for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
416     {
417       /* Rb and Re may be SP_REGNUM.
418          We need to break this loop immediately.  */
419       if (regno == SP_REGNUM)
420         break;
421 
422       reg = gen_rtx_REG (SImode, regno);
423       mem = gen_frame_mem (SImode, plus_constant (Pmode,
424 						  stack_pointer_rtx,
425 						  offset));
426       push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
427       XVECEXP (parallel_insn, 0, par_index) = push_rtx;
428       RTX_FRAME_RELATED_P (push_rtx) = 1;
429       offset = offset + 4;
430       par_index++;
431     }
432 
433   /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary.  */
434   if (cfun->machine->fp_size)
435     {
436       reg = gen_rtx_REG (SImode, FP_REGNUM);
437       mem = gen_frame_mem (SImode, plus_constant (Pmode,
438 						  stack_pointer_rtx,
439 						  offset));
440       push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
441       XVECEXP (parallel_insn, 0, par_index) = push_rtx;
442       RTX_FRAME_RELATED_P (push_rtx) = 1;
443       offset = offset + 4;
444       par_index++;
445     }
446   if (cfun->machine->gp_size)
447     {
448       reg = gen_rtx_REG (SImode, GP_REGNUM);
449       mem = gen_frame_mem (SImode, plus_constant (Pmode,
450 						  stack_pointer_rtx,
451 						  offset));
452       push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
453       XVECEXP (parallel_insn, 0, par_index) = push_rtx;
454       RTX_FRAME_RELATED_P (push_rtx) = 1;
455       offset = offset + 4;
456       par_index++;
457     }
458   if (cfun->machine->lp_size)
459     {
460       reg = gen_rtx_REG (SImode, LP_REGNUM);
461       mem = gen_frame_mem (SImode, plus_constant (Pmode,
462 						  stack_pointer_rtx,
463 						  offset));
464       push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
465       XVECEXP (parallel_insn, 0, par_index) = push_rtx;
466       RTX_FRAME_RELATED_P (push_rtx) = 1;
467       offset = offset + 4;
468       par_index++;
469     }
470 
471   /* Create (set sp sp-x).  */
472 
473   /* We need to re-calculate the offset value again for adjustment.  */
474   offset = -(num_use_regs * 4);
475   adjust_sp_rtx
476     = gen_rtx_SET (VOIDmode,
477 		   stack_pointer_rtx,
478 		   plus_constant (Pmode, stack_pointer_rtx, offset));
479   XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
480   RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
481 
482   return parallel_insn;
483 }
484 
485 /* Function to create a parallel rtx pattern
486    which presents stack pop multiple behavior.
487    The overall concept are:
488      "pop registers from memory",
489      "adjust stack pointer".  */
490 static rtx
nds32_gen_stack_pop_multiple(rtx Rb,rtx Re,rtx En4 ATTRIBUTE_UNUSED)491 nds32_gen_stack_pop_multiple (rtx Rb, rtx Re,
492 			      rtx En4 ATTRIBUTE_UNUSED)
493 {
494   int regno;
495   int extra_count;
496   int num_use_regs;
497   int par_index;
498   int offset;
499 
500   rtx reg;
501   rtx mem;
502   rtx pop_rtx;
503   rtx adjust_sp_rtx;
504   rtx parallel_insn;
505 
506   /* We need to provide a customized rtx which contains
507      necessary information for data analysis,
508      so we create a parallel rtx like this:
509      (parallel [(set (reg:SI Rb)
510                      (mem (reg:SI SP_REGNUM)))
511                 (set (reg:SI Rb+1)
512                      (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
513                 ...
514                 (set (reg:SI Re)
515                      (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
516                 (set (reg:SI FP_REGNUM)
517                      (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
518                 (set (reg:SI GP_REGNUM)
519                      (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
520                 (set (reg:SI LP_REGNUM)
521                      (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
522                 (set (reg:SI SP_REGNUM)
523                      (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
524 
525   /* Calculate the number of registers that will be poped.  */
526   extra_count = 0;
527   if (cfun->machine->fp_size)
528     extra_count++;
529   if (cfun->machine->gp_size)
530     extra_count++;
531   if (cfun->machine->lp_size)
532     extra_count++;
533   /* Note that Rb and Re may be SP_REGNUM.  DO NOT count it in.  */
534   if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
535     num_use_regs = extra_count;
536   else
537     num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
538 
539   /* In addition to used registers,
540      we need one more space for (set sp sp+x) rtx.  */
541   parallel_insn = gen_rtx_PARALLEL (VOIDmode,
542 				    rtvec_alloc (num_use_regs + 1));
543   par_index = 0;
544 
545   /* Initialize offset and start to create pop behavior.  */
546   offset = 0;
547 
548   /* Create (set regX mem) from Rb, Rb+1 up to Re.  */
549   for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
550     {
551       /* Rb and Re may be SP_REGNUM.
552          We need to break this loop immediately.  */
553       if (regno == SP_REGNUM)
554         break;
555 
556       reg = gen_rtx_REG (SImode, regno);
557       mem = gen_frame_mem (SImode, plus_constant (Pmode,
558 						  stack_pointer_rtx,
559 						  offset));
560       pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
561       XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
562       RTX_FRAME_RELATED_P (pop_rtx) = 1;
563       offset = offset + 4;
564       par_index++;
565     }
566 
567   /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary.  */
568   if (cfun->machine->fp_size)
569     {
570       reg = gen_rtx_REG (SImode, FP_REGNUM);
571       mem = gen_frame_mem (SImode, plus_constant (Pmode,
572 						  stack_pointer_rtx,
573 						  offset));
574       pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
575       XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
576       RTX_FRAME_RELATED_P (pop_rtx) = 1;
577       offset = offset + 4;
578       par_index++;
579     }
580   if (cfun->machine->gp_size)
581     {
582       reg = gen_rtx_REG (SImode, GP_REGNUM);
583       mem = gen_frame_mem (SImode, plus_constant (Pmode,
584 						  stack_pointer_rtx,
585 						  offset));
586       pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
587       XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
588       RTX_FRAME_RELATED_P (pop_rtx) = 1;
589       offset = offset + 4;
590       par_index++;
591     }
592   if (cfun->machine->lp_size)
593     {
594       reg = gen_rtx_REG (SImode, LP_REGNUM);
595       mem = gen_frame_mem (SImode, plus_constant (Pmode,
596 						  stack_pointer_rtx,
597 						  offset));
598       pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
599       XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
600       RTX_FRAME_RELATED_P (pop_rtx) = 1;
601       offset = offset + 4;
602       par_index++;
603     }
604 
605   /* Create (set sp sp+x).  */
606 
607   /* The offset value is already in place.  No need to re-calculate it.  */
608   adjust_sp_rtx
609     = gen_rtx_SET (VOIDmode,
610 		   stack_pointer_rtx,
611 		   plus_constant (Pmode, stack_pointer_rtx, offset));
612   XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
613   RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
614 
615   return parallel_insn;
616 }
617 
618 /* Function to create a parallel rtx pattern
619    which presents stack v3push behavior.
620    The overall concept are:
621      "push registers to memory",
622      "adjust stack pointer".  */
623 static rtx
nds32_gen_stack_v3push(rtx Rb,rtx Re,rtx En4 ATTRIBUTE_UNUSED,rtx imm8u)624 nds32_gen_stack_v3push (rtx Rb,
625 			rtx Re,
626 			rtx En4 ATTRIBUTE_UNUSED,
627 			rtx imm8u)
628 {
629   int regno;
630   int num_use_regs;
631   int par_index;
632   int offset;
633 
634   rtx reg;
635   rtx mem;
636   rtx push_rtx;
637   rtx adjust_sp_rtx;
638   rtx parallel_insn;
639 
640   /* We need to provide a customized rtx which contains
641      necessary information for data analysis,
642      so we create a parallel rtx like this:
643      (parallel [
644                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
645                      (reg:SI Rb))
646                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
647                      (reg:SI Rb+1))
648                 ...
649                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
650                      (reg:SI Re))
651                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
652                      (reg:SI FP_REGNUM))
653                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
654                      (reg:SI GP_REGNUM))
655                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
656                      (reg:SI LP_REGNUM))
657                 (set (reg:SI SP_REGNUM)
658                      (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
659 
660   /* Calculate the number of registers that will be pushed.
661      Since $fp, $gp, and $lp is always pushed with v3push instruction,
662      we need to count these three registers.
663      Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
664      So there is no need to worry about Rb=Re=SP_REGNUM case.  */
665   num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
666 
667   /* In addition to used registers,
668      we need one more space for (set sp sp-x-imm8u) rtx.  */
669   parallel_insn = gen_rtx_PARALLEL (VOIDmode,
670 				    rtvec_alloc (num_use_regs + 1));
671   par_index = 0;
672 
673   /* Initialize offset and start to create push behavior.  */
674   offset = -(num_use_regs * 4);
675 
676   /* Create (set mem regX) from Rb, Rb+1 up to Re.
677      Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
678      So there is no need to worry about Rb=Re=SP_REGNUM case.  */
679   for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
680     {
681       reg = gen_rtx_REG (SImode, regno);
682       mem = gen_frame_mem (SImode, plus_constant (Pmode,
683 						  stack_pointer_rtx,
684 						  offset));
685       push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
686       XVECEXP (parallel_insn, 0, par_index) = push_rtx;
687       RTX_FRAME_RELATED_P (push_rtx) = 1;
688       offset = offset + 4;
689       par_index++;
690     }
691 
692   /* Create (set mem fp).  */
693   reg = gen_rtx_REG (SImode, FP_REGNUM);
694   mem = gen_frame_mem (SImode, plus_constant (Pmode,
695 					      stack_pointer_rtx,
696 					      offset));
697   push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
698   XVECEXP (parallel_insn, 0, par_index) = push_rtx;
699   RTX_FRAME_RELATED_P (push_rtx) = 1;
700   offset = offset + 4;
701   par_index++;
702   /* Create (set mem gp).  */
703   reg = gen_rtx_REG (SImode, GP_REGNUM);
704   mem = gen_frame_mem (SImode, plus_constant (Pmode,
705 					      stack_pointer_rtx,
706 					      offset));
707   push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
708   XVECEXP (parallel_insn, 0, par_index) = push_rtx;
709   RTX_FRAME_RELATED_P (push_rtx) = 1;
710   offset = offset + 4;
711   par_index++;
712   /* Create (set mem lp).  */
713   reg = gen_rtx_REG (SImode, LP_REGNUM);
714   mem = gen_frame_mem (SImode, plus_constant (Pmode,
715 					      stack_pointer_rtx,
716 					      offset));
717   push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
718   XVECEXP (parallel_insn, 0, par_index) = push_rtx;
719   RTX_FRAME_RELATED_P (push_rtx) = 1;
720   offset = offset + 4;
721   par_index++;
722 
723   /* Create (set sp sp-x-imm8u).  */
724 
725   /* We need to re-calculate the offset value again for adjustment.  */
726   offset = -(num_use_regs * 4);
727   adjust_sp_rtx
728     = gen_rtx_SET (VOIDmode,
729 		   stack_pointer_rtx,
730 		   plus_constant (Pmode,
731 				  stack_pointer_rtx,
732 				  offset - INTVAL (imm8u)));
733   XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
734   RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
735 
736   return parallel_insn;
737 }
738 
739 /* Function to create a parallel rtx pattern
740    which presents stack v3pop behavior.
741    The overall concept are:
742      "pop registers from memory",
743      "adjust stack pointer".  */
744 static rtx
nds32_gen_stack_v3pop(rtx Rb,rtx Re,rtx En4 ATTRIBUTE_UNUSED,rtx imm8u)745 nds32_gen_stack_v3pop (rtx Rb,
746 		       rtx Re,
747 		       rtx En4 ATTRIBUTE_UNUSED,
748 		       rtx imm8u)
749 {
750   int regno;
751   int num_use_regs;
752   int par_index;
753   int offset;
754 
755   rtx reg;
756   rtx mem;
757   rtx pop_rtx;
758   rtx adjust_sp_rtx;
759   rtx parallel_insn;
760 
761   /* We need to provide a customized rtx which contains
762      necessary information for data analysis,
763      so we create a parallel rtx like this:
764      (parallel [(set (reg:SI Rb)
765                      (mem (reg:SI SP_REGNUM)))
766                 (set (reg:SI Rb+1)
767                      (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
768                 ...
769                 (set (reg:SI Re)
770                      (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
771                 (set (reg:SI FP_REGNUM)
772                      (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
773                 (set (reg:SI GP_REGNUM)
774                      (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
775                 (set (reg:SI LP_REGNUM)
776                      (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
777                 (set (reg:SI SP_REGNUM)
778                      (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
779 
780   /* Calculate the number of registers that will be poped.
781      Since $fp, $gp, and $lp is always poped with v3pop instruction,
782      we need to count these three registers.
783      Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
784      So there is no need to worry about Rb=Re=SP_REGNUM case.  */
785   num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
786 
787   /* In addition to used registers,
788      we need one more space for (set sp sp+x+imm8u) rtx.  */
789   parallel_insn = gen_rtx_PARALLEL (VOIDmode,
790 				    rtvec_alloc (num_use_regs + 1));
791   par_index = 0;
792 
793   /* Initialize offset and start to create pop behavior.  */
794   offset = 0;
795 
796   /* Create (set regX mem) from Rb, Rb+1 up to Re.
797      Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
798      So there is no need to worry about Rb=Re=SP_REGNUM case.  */
799   for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
800     {
801       reg = gen_rtx_REG (SImode, regno);
802       mem = gen_frame_mem (SImode, plus_constant (Pmode,
803 						  stack_pointer_rtx,
804 						  offset));
805       pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
806       XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
807       RTX_FRAME_RELATED_P (pop_rtx) = 1;
808       offset = offset + 4;
809       par_index++;
810     }
811 
812   /* Create (set fp mem).  */
813   reg = gen_rtx_REG (SImode, FP_REGNUM);
814   mem = gen_frame_mem (SImode, plus_constant (Pmode,
815 					      stack_pointer_rtx,
816 					      offset));
817   pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
818   XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
819   RTX_FRAME_RELATED_P (pop_rtx) = 1;
820   offset = offset + 4;
821   par_index++;
822   /* Create (set gp mem).  */
823   reg = gen_rtx_REG (SImode, GP_REGNUM);
824   mem = gen_frame_mem (SImode, plus_constant (Pmode,
825 					      stack_pointer_rtx,
826 					      offset));
827   pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
828   XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
829   RTX_FRAME_RELATED_P (pop_rtx) = 1;
830   offset = offset + 4;
831   par_index++;
832   /* Create (set lp mem ).  */
833   reg = gen_rtx_REG (SImode, LP_REGNUM);
834   mem = gen_frame_mem (SImode, plus_constant (Pmode,
835 					      stack_pointer_rtx,
836 					      offset));
837   pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
838   XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
839   RTX_FRAME_RELATED_P (pop_rtx) = 1;
840   offset = offset + 4;
841   par_index++;
842 
843   /* Create (set sp sp+x+imm8u).  */
844 
845   /* The offset value is already in place.  No need to re-calculate it.  */
846   adjust_sp_rtx
847     = gen_rtx_SET (VOIDmode,
848 		   stack_pointer_rtx,
849 		   plus_constant (Pmode,
850 				  stack_pointer_rtx,
851 				  offset + INTVAL (imm8u)));
852   XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
853   RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
854 
855   return parallel_insn;
856 }
857 
858 /* A subroutine that checks multiple load and store
859    using consecutive registers.
860      OP is a parallel rtx we would like to check.
861      LOAD_P indicates whether we are checking load operation.
862      PAR_INDEX is starting element of parallel rtx.
863      FIRST_ELT_REGNO is used to tell starting register number.
864      COUNT helps us to check consecutive register numbers.  */
865 static bool
nds32_consecutive_registers_load_store_p(rtx op,bool load_p,int par_index,int first_elt_regno,int count)866 nds32_consecutive_registers_load_store_p (rtx op,
867 					  bool load_p,
868 					  int par_index,
869 					  int first_elt_regno,
870 					  int count)
871 {
872   int i;
873   int check_regno;
874   rtx elt;
875   rtx elt_reg;
876   rtx elt_mem;
877 
878   for (i = 0; i < count; i++)
879     {
880       /* Pick up each element from parallel rtx.  */
881       elt = XVECEXP (op, 0, i + par_index);
882 
883       /* If this element is not a 'set' rtx, return false immediately.  */
884       if (GET_CODE (elt) != SET)
885 	return false;
886 
887       /* Pick up reg and mem of this element.  */
888       elt_reg = load_p ? SET_DEST (elt) : SET_SRC (elt);
889       elt_mem = load_p ? SET_SRC (elt) : SET_DEST (elt);
890 
891       /* If elt_reg is not a expected reg rtx, return false.  */
892       if (GET_CODE (elt_reg) != REG || GET_MODE (elt_reg) != SImode)
893 	return false;
894       /* If elt_mem is not a expected mem rtx, return false.  */
895       if (GET_CODE (elt_mem) != MEM || GET_MODE (elt_mem) != SImode)
896 	return false;
897 
898       /* The consecutive registers should be in (Rb,Rb+1...Re) order.  */
899       check_regno = first_elt_regno + i;
900 
901       /* If the register number is not continuous, return false.  */
902       if (REGNO (elt_reg) != (unsigned int) check_regno)
903 	return false;
904     }
905 
906   return true;
907 }
908 
909 /* A helper function to emit section head template.  */
910 static void
nds32_emit_section_head_template(char section_name[],char symbol_name[],int align_value,bool object_p)911 nds32_emit_section_head_template (char section_name[],
912 				  char symbol_name[],
913 				  int align_value,
914 				  bool object_p)
915 {
916   const char *flags_str;
917   const char *type_str;
918 
919   flags_str = (object_p) ? "\"a\"" : "\"ax\"";
920   type_str = (object_p) ? "@object" : "@function";
921 
922   fprintf (asm_out_file, "\t.section\t%s, %s\n", section_name, flags_str);
923   fprintf (asm_out_file, "\t.align\t%d\n", align_value);
924   fprintf (asm_out_file, "\t.global\t%s\n", symbol_name);
925   fprintf (asm_out_file, "\t.type\t%s, %s\n", symbol_name, type_str);
926   fprintf (asm_out_file, "%s:\n", symbol_name);
927 }
928 
929 /* A helper function to emit section tail template.  */
930 static void
nds32_emit_section_tail_template(char symbol_name[])931 nds32_emit_section_tail_template (char symbol_name[])
932 {
933   fprintf (asm_out_file, "\t.size\t%s, .-%s\n", symbol_name, symbol_name);
934 }
935 
936 /* Function to emit isr jump table section.  */
937 static void
nds32_emit_isr_jmptbl_section(int vector_id)938 nds32_emit_isr_jmptbl_section (int vector_id)
939 {
940   char section_name[100];
941   char symbol_name[100];
942 
943   /* Prepare jmptbl section and symbol name.  */
944   snprintf (section_name, sizeof (section_name),
945 	    ".nds32_jmptbl.%02d", vector_id);
946   snprintf (symbol_name, sizeof (symbol_name),
947 	    "_nds32_jmptbl_%02d", vector_id);
948 
949   nds32_emit_section_head_template (section_name, symbol_name, 2, true);
950   fprintf (asm_out_file, "\t.word\t%s\n",
951 			 nds32_isr_vectors[vector_id].func_name);
952   nds32_emit_section_tail_template (symbol_name);
953 }
954 
955 /* Function to emit isr vector section.  */
956 static void
nds32_emit_isr_vector_section(int vector_id)957 nds32_emit_isr_vector_section (int vector_id)
958 {
959   unsigned int vector_number_offset = 0;
960   const char *c_str = "CATEGORY";
961   const char *sr_str = "SR";
962   const char *nt_str = "NT";
963   const char *vs_str = "VS";
964   char first_level_handler_name[100];
965   char section_name[100];
966   char symbol_name[100];
967 
968   /* Set the vector number offset so that we can calculate
969      the value that user specifies in the attribute.
970      We also prepare the category string for first level handler name.  */
971   switch (nds32_isr_vectors[vector_id].category)
972     {
973     case NDS32_ISR_INTERRUPT:
974       vector_number_offset = 9;
975       c_str = "i";
976       break;
977     case NDS32_ISR_EXCEPTION:
978       vector_number_offset = 0;
979       c_str = "e";
980       break;
981     case NDS32_ISR_NONE:
982     case NDS32_ISR_RESET:
983       /* Normally it should not be here.  */
984       gcc_unreachable ();
985       break;
986     }
987 
988   /* Prepare save reg string for first level handler name.  */
989   switch (nds32_isr_vectors[vector_id].save_reg)
990     {
991     case NDS32_SAVE_ALL:
992       sr_str = "sa";
993       break;
994     case NDS32_PARTIAL_SAVE:
995       sr_str = "ps";
996       break;
997     }
998 
999   /* Prepare nested type string for first level handler name.  */
1000   switch (nds32_isr_vectors[vector_id].nested_type)
1001     {
1002     case NDS32_NESTED:
1003       nt_str = "ns";
1004       break;
1005     case NDS32_NOT_NESTED:
1006       nt_str = "nn";
1007       break;
1008     case NDS32_NESTED_READY:
1009       nt_str = "nr";
1010       break;
1011     }
1012 
1013   /* Currently we have 4-byte or 16-byte size for each vector.
1014      If it is 4-byte, the first level handler name has suffix string "_4b".  */
1015   vs_str = (nds32_isr_vector_size == 4) ? "_4b" : "";
1016 
1017   /* Now we can create first level handler name.  */
1018   snprintf (first_level_handler_name, sizeof (first_level_handler_name),
1019 	    "_nds32_%s_%s_%s%s", c_str, sr_str, nt_str, vs_str);
1020 
1021   /* Prepare vector section and symbol name.  */
1022   snprintf (section_name, sizeof (section_name),
1023 	    ".nds32_vector.%02d", vector_id);
1024   snprintf (symbol_name, sizeof (symbol_name),
1025 	    "_nds32_vector_%02d%s", vector_id, vs_str);
1026 
1027 
1028   /* Everything is ready.  We can start emit vector section content.  */
1029   nds32_emit_section_head_template (section_name, symbol_name,
1030 				    floor_log2 (nds32_isr_vector_size), false);
1031 
1032   /* According to the vector size, the instructions in the
1033      vector section may be different.  */
1034   if (nds32_isr_vector_size == 4)
1035     {
1036       /* This block is for 4-byte vector size.
1037          Hardware $VID support is necessary and only one instruction
1038          is needed in vector section.  */
1039       fprintf (asm_out_file, "\tj\t%s ! jump to first level handler\n",
1040 			     first_level_handler_name);
1041     }
1042   else
1043     {
1044       /* This block is for 16-byte vector size.
1045          There is NO hardware $VID so that we need several instructions
1046          such as pushing GPRs and preparing software vid at vector section.
1047          For pushing GPRs, there are four variations for
1048          16-byte vector content and we have to handle each combination.
1049          For preparing software vid, note that the vid need to
1050          be substracted vector_number_offset.  */
1051       if (TARGET_REDUCED_REGS)
1052 	{
1053 	  if (nds32_isr_vectors[vector_id].save_reg == NDS32_SAVE_ALL)
1054 	    {
1055 	      /* Case of reduced set registers and save_all attribute.  */
1056 	      fprintf (asm_out_file, "\t! reduced set regs + save_all\n");
1057 	      fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r15, 0xf\n");
1058 	      fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r10, 0x0\n");
1059 
1060 	    }
1061 	  else
1062 	    {
1063 	      /* Case of reduced set registers and partial_save attribute.  */
1064 	      fprintf (asm_out_file, "\t! reduced set regs + partial_save\n");
1065 	      fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r15, 0x2\n");
1066 	      fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r5, 0x0\n");
1067 	    }
1068 	}
1069       else
1070 	{
1071 	  if (nds32_isr_vectors[vector_id].save_reg == NDS32_SAVE_ALL)
1072 	    {
1073 	      /* Case of full set registers and save_all attribute.  */
1074 	      fprintf (asm_out_file, "\t! full set regs + save_all\n");
1075 	      fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r27, 0xf\n");
1076 	    }
1077 	  else
1078 	    {
1079 	      /* Case of full set registers and partial_save attribute.  */
1080 	      fprintf (asm_out_file, "\t! full set regs + partial_save\n");
1081 	      fprintf (asm_out_file, "\tsmw.adm\t$r15, [$sp], $r27, 0x2\n");
1082 	      fprintf (asm_out_file, "\tsmw.adm\t$r0, [$sp], $r5, 0x0\n");
1083 	    }
1084 	}
1085 
1086       fprintf (asm_out_file, "\tmovi\t$r0, %d ! preparing software vid\n",
1087 			     vector_id - vector_number_offset);
1088       fprintf (asm_out_file, "\tj\t%s ! jump to first level handler\n",
1089 			     first_level_handler_name);
1090     }
1091 
1092   nds32_emit_section_tail_template (symbol_name);
1093 }
1094 
1095 /* Function to emit isr reset handler content.
1096    Including all jmptbl/vector references, jmptbl section,
1097    vector section, nmi handler section, and warm handler section.  */
1098 static void
nds32_emit_isr_reset_content(void)1099 nds32_emit_isr_reset_content (void)
1100 {
1101   unsigned int i;
1102   unsigned int total_n_vectors;
1103   const char *vs_str;
1104   char reset_handler_name[100];
1105   char section_name[100];
1106   char symbol_name[100];
1107 
1108   total_n_vectors = nds32_isr_vectors[0].total_n_vectors;
1109   vs_str = (nds32_isr_vector_size == 4) ? "_4b" : "";
1110 
1111   fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - BEGIN !\n");
1112 
1113   /* Create references in .rodata according to total number of vectors.  */
1114   fprintf (asm_out_file, "\t.section\t.rodata\n");
1115   fprintf (asm_out_file, "\t.align\t2\n");
1116 
1117   /* Emit jmptbl references.  */
1118   fprintf (asm_out_file, "\t ! references to jmptbl section entries\n");
1119   for (i = 0; i < total_n_vectors; i++)
1120     fprintf (asm_out_file, "\t.word\t_nds32_jmptbl_%02d\n", i);
1121 
1122   /* Emit vector references.  */
1123   fprintf (asm_out_file, "\t ! references to vector section entries\n");
1124   for (i = 0; i < total_n_vectors; i++)
1125     fprintf (asm_out_file, "\t.word\t_nds32_vector_%02d%s\n", i, vs_str);
1126 
1127   /* Emit jmptbl_00 section.  */
1128   snprintf (section_name, sizeof (section_name), ".nds32_jmptbl.00");
1129   snprintf (symbol_name, sizeof (symbol_name), "_nds32_jmptbl_00");
1130 
1131   fprintf (asm_out_file, "\t! ....................................\n");
1132   nds32_emit_section_head_template (section_name, symbol_name, 2, true);
1133   fprintf (asm_out_file, "\t.word\t%s\n",
1134 			 nds32_isr_vectors[0].func_name);
1135   nds32_emit_section_tail_template (symbol_name);
1136 
1137   /* Emit vector_00 section.  */
1138   snprintf (section_name, sizeof (section_name), ".nds32_vector.00");
1139   snprintf (symbol_name, sizeof (symbol_name), "_nds32_vector_00%s", vs_str);
1140   snprintf (reset_handler_name, sizeof (reset_handler_name),
1141 	    "_nds32_reset%s", vs_str);
1142 
1143   fprintf (asm_out_file, "\t! ....................................\n");
1144   nds32_emit_section_head_template (section_name, symbol_name,
1145 				    floor_log2 (nds32_isr_vector_size), false);
1146   fprintf (asm_out_file, "\tj\t%s ! jump to reset handler\n",
1147 			 reset_handler_name);
1148   nds32_emit_section_tail_template (symbol_name);
1149 
1150   /* Emit nmi handler section.  */
1151   snprintf (section_name, sizeof (section_name), ".nds32_nmih");
1152   snprintf (symbol_name, sizeof (symbol_name), "_nds32_nmih");
1153 
1154   fprintf (asm_out_file, "\t! ....................................\n");
1155   nds32_emit_section_head_template (section_name, symbol_name, 2, true);
1156   fprintf (asm_out_file, "\t.word\t%s\n",
1157 			 (strlen (nds32_isr_vectors[0].nmi_name) == 0)
1158 			 ? "0"
1159 			 : nds32_isr_vectors[0].nmi_name);
1160   nds32_emit_section_tail_template (symbol_name);
1161 
1162   /* Emit warm handler section.  */
1163   snprintf (section_name, sizeof (section_name), ".nds32_wrh");
1164   snprintf (symbol_name, sizeof (symbol_name), "_nds32_wrh");
1165 
1166   fprintf (asm_out_file, "\t! ....................................\n");
1167   nds32_emit_section_head_template (section_name, symbol_name, 2, true);
1168   fprintf (asm_out_file, "\t.word\t%s\n",
1169 			 (strlen (nds32_isr_vectors[0].warm_name) == 0)
1170 			 ? "0"
1171 			 : nds32_isr_vectors[0].warm_name);
1172   nds32_emit_section_tail_template (symbol_name);
1173 
1174   fprintf (asm_out_file, "\t! RESET HANDLER CONTENT - END !\n");
1175 }
1176 
1177 /* Function for nds32_merge_decl_attributes() and nds32_insert_attributes()
1178    to check if there are any conflict isr-specific attributes being set.
1179    We need to check:
1180      1. Only 'save_all' or 'partial_save' in the attributes.
1181      2. Only 'nested', 'not_nested', or 'nested_ready' in the attributes.
1182      3. Only 'interrupt', 'exception', or 'reset' in the attributes.  */
1183 static void
nds32_check_isr_attrs_conflict(tree func_decl,tree func_attrs)1184 nds32_check_isr_attrs_conflict (tree func_decl, tree func_attrs)
1185 {
1186   int save_all_p, partial_save_p;
1187   int nested_p, not_nested_p, nested_ready_p;
1188   int intr_p, excp_p, reset_p;
1189 
1190   /* Initialize variables.  */
1191   save_all_p = partial_save_p = 0;
1192   nested_p = not_nested_p = nested_ready_p = 0;
1193   intr_p = excp_p = reset_p = 0;
1194 
1195   /* We must check at MOST one attribute to set save-reg.  */
1196   if (lookup_attribute ("save_all", func_attrs))
1197     save_all_p = 1;
1198   if (lookup_attribute ("partial_save", func_attrs))
1199     partial_save_p = 1;
1200 
1201   if ((save_all_p + partial_save_p) > 1)
1202     error ("multiple save reg attributes to function %qD", func_decl);
1203 
1204   /* We must check at MOST one attribute to set nested-type.  */
1205   if (lookup_attribute ("nested", func_attrs))
1206     nested_p = 1;
1207   if (lookup_attribute ("not_nested", func_attrs))
1208     not_nested_p = 1;
1209   if (lookup_attribute ("nested_ready", func_attrs))
1210     nested_ready_p = 1;
1211 
1212   if ((nested_p + not_nested_p + nested_ready_p) > 1)
1213     error ("multiple nested types attributes to function %qD", func_decl);
1214 
1215   /* We must check at MOST one attribute to
1216      set interrupt/exception/reset.  */
1217   if (lookup_attribute ("interrupt", func_attrs))
1218     intr_p = 1;
1219   if (lookup_attribute ("exception", func_attrs))
1220     excp_p = 1;
1221   if (lookup_attribute ("reset", func_attrs))
1222     reset_p = 1;
1223 
1224   if ((intr_p + excp_p + reset_p) > 1)
1225     error ("multiple interrupt attributes to function %qD", func_decl);
1226 }
1227 
1228 /* Function to construct isr vectors information array.
1229    We DO NOT HAVE TO check if the attributes are valid
1230    because those works are supposed to be done on
1231    nds32_merge_decl_attributes() and nds32_insert_attributes().  */
1232 static void
nds32_construct_isr_vectors_information(tree func_attrs,const char * func_name)1233 nds32_construct_isr_vectors_information (tree func_attrs,
1234 					 const char *func_name)
1235 {
1236   tree save_all, partial_save;
1237   tree nested, not_nested, nested_ready;
1238   tree intr, excp, reset;
1239 
1240   save_all     = lookup_attribute ("save_all", func_attrs);
1241   partial_save = lookup_attribute ("partial_save", func_attrs);
1242 
1243   nested       = lookup_attribute ("nested", func_attrs);
1244   not_nested   = lookup_attribute ("not_nested", func_attrs);
1245   nested_ready = lookup_attribute ("nested_ready", func_attrs);
1246 
1247   intr  = lookup_attribute ("interrupt", func_attrs);
1248   excp  = lookup_attribute ("exception", func_attrs);
1249   reset = lookup_attribute ("reset", func_attrs);
1250 
1251   /* If there is no interrupt/exception/reset, we can return immediately.  */
1252   if (!intr && !excp && !reset)
1253     return;
1254 
1255   /* If we are here, either we have interrupt/exception,
1256      or reset attribute.  */
1257   if (intr || excp)
1258     {
1259       tree id_list;
1260 
1261       /* Prepare id list so that we can traverse and set vector id.  */
1262       id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
1263 
1264       while (id_list)
1265 	{
1266 	  tree id;
1267 	  int vector_id;
1268 	  unsigned int vector_number_offset;
1269 
1270 	  /* The way to handle interrupt or exception is the same,
1271 	     we just need to take care of actual vector number.
1272 	     For interrupt(0..63), the actual vector number is (9..72).
1273 	     For exception(1..8), the actual vector number is (1..8).  */
1274 	  vector_number_offset = (intr) ? (9) : (0);
1275 
1276 	  /* Pick up each vector id value.  */
1277 	  id = TREE_VALUE (id_list);
1278 	  /* Add vector_number_offset to get actual vector number.  */
1279 	  vector_id = TREE_INT_CST_LOW (id) + vector_number_offset;
1280 
1281 	  /* Enable corresponding vector and set function name.  */
1282 	  nds32_isr_vectors[vector_id].category = (intr)
1283 						  ? (NDS32_ISR_INTERRUPT)
1284 						  : (NDS32_ISR_EXCEPTION);
1285 	  strcpy (nds32_isr_vectors[vector_id].func_name, func_name);
1286 
1287 	  /* Set register saving scheme.  */
1288 	  if (save_all)
1289 	    nds32_isr_vectors[vector_id].save_reg = NDS32_SAVE_ALL;
1290 	  else if (partial_save)
1291 	    nds32_isr_vectors[vector_id].save_reg = NDS32_PARTIAL_SAVE;
1292 
1293 	  /* Set nested type.  */
1294 	  if (nested)
1295 	    nds32_isr_vectors[vector_id].nested_type = NDS32_NESTED;
1296 	  else if (not_nested)
1297 	    nds32_isr_vectors[vector_id].nested_type = NDS32_NOT_NESTED;
1298 	  else if (nested_ready)
1299 	    nds32_isr_vectors[vector_id].nested_type = NDS32_NESTED_READY;
1300 
1301 	  /* Advance to next id.  */
1302 	  id_list = TREE_CHAIN (id_list);
1303 	}
1304     }
1305   else
1306     {
1307       tree id_list;
1308       tree id;
1309       tree nmi, warm;
1310 
1311       /* Deal with reset attribute.  Its vector number is always 0.  */
1312       nds32_isr_vectors[0].category = NDS32_ISR_RESET;
1313 
1314       /* Prepare id_list and identify id value so that
1315          we can set total number of vectors.  */
1316       id_list = TREE_VALUE (reset);
1317       id = TREE_VALUE (id_list);
1318 
1319       /* The total vectors = interrupt + exception numbers + reset.
1320          There are 8 exception and 1 reset in nds32 architecture.  */
1321       nds32_isr_vectors[0].total_n_vectors = TREE_INT_CST_LOW (id) + 8 + 1;
1322       strcpy (nds32_isr_vectors[0].func_name, func_name);
1323 
1324       /* Retrieve nmi and warm function.  */
1325       nmi  = lookup_attribute ("nmi", func_attrs);
1326       warm = lookup_attribute ("warm", func_attrs);
1327 
1328       if (nmi != NULL_TREE)
1329 	{
1330 	  tree nmi_func_list;
1331 	  tree nmi_func;
1332 
1333 	  nmi_func_list = TREE_VALUE (nmi);
1334 	  nmi_func = TREE_VALUE (nmi_func_list);
1335 
1336 	  /* Record nmi function name.  */
1337 	  strcpy (nds32_isr_vectors[0].nmi_name,
1338 		  IDENTIFIER_POINTER (nmi_func));
1339 	}
1340 
1341       if (warm != NULL_TREE)
1342 	{
1343 	  tree warm_func_list;
1344 	  tree warm_func;
1345 
1346 	  warm_func_list = TREE_VALUE (warm);
1347 	  warm_func = TREE_VALUE (warm_func_list);
1348 
1349 	  /* Record warm function name.  */
1350 	  strcpy (nds32_isr_vectors[0].warm_name,
1351 		  IDENTIFIER_POINTER (warm_func));
1352 	}
1353     }
1354 }
1355 
1356 /* Function that may creates more instructions
1357    for large value on adjusting stack pointer.
1358 
1359    In nds32 target, 'addi' can be used for stack pointer
1360    adjustment in prologue/epilogue stage.
1361    However, sometimes there are too many local variables so that
1362    the adjustment value is not able to be fit in the 'addi' instruction.
1363    One solution is to move value into a register
1364    and then use 'add' instruction.
1365    In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
1366    Also, we need to return zero for sp adjustment so that
1367    proglogue/epilogue knows there is no need to create 'addi' instruction.  */
1368 static int
nds32_force_addi_stack_int(int full_value)1369 nds32_force_addi_stack_int (int full_value)
1370 {
1371   int adjust_value;
1372 
1373   rtx tmp_reg;
1374   rtx sp_adjust_insn;
1375 
1376   if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
1377     {
1378       /* The value is not able to fit in single addi instruction.
1379          Create more instructions of moving value into a register
1380          and then add stack pointer with it.  */
1381 
1382       /* $r15 is going to be temporary register to hold the value.  */
1383       tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1384 
1385       /* Create one more instruction to move value
1386          into the temporary register.  */
1387       emit_move_insn (tmp_reg, GEN_INT (full_value));
1388 
1389       /* Create new 'add' rtx.  */
1390       sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
1391 				   stack_pointer_rtx,
1392 				   tmp_reg);
1393       /* Emit rtx into insn list and receive its transformed insn rtx.  */
1394       sp_adjust_insn = emit_insn (sp_adjust_insn);
1395 
1396       /* At prologue, we need to tell GCC that this is frame related insn,
1397          so that we can consider this instruction to output debug information.
1398          If full_value is NEGATIVE, it means this function
1399          is invoked by expand_prologue.  */
1400       if (full_value < 0)
1401 	{
1402 	  /* Because (tmp_reg <- full_value) may be split into two
1403 	     rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1404 	     We need to construct another (sp <- sp + full_value)
1405 	     and then insert it into sp_adjust_insn's reg note to
1406 	     represent a frame related expression.
1407 	     GCC knows how to refer it and output debug information.  */
1408 
1409 	  rtx plus_rtx;
1410 	  rtx set_rtx;
1411 
1412 	  plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
1413 	  set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
1414 	  add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
1415 
1416 	  RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
1417 	}
1418 
1419       /* We have used alternative way to adjust stack pointer value.
1420          Return zero so that prologue/epilogue
1421          will not generate other instructions.  */
1422       return 0;
1423     }
1424   else
1425     {
1426       /* The value is able to fit in addi instruction.
1427          However, remember to make it to be positive value
1428          because we want to return 'adjustment' result.  */
1429       adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1430 
1431       return adjust_value;
1432     }
1433 }
1434 
1435 /* Return true if MODE/TYPE need double word alignment.  */
1436 static bool
nds32_needs_double_word_align(enum machine_mode mode,const_tree type)1437 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
1438 {
1439   unsigned int align;
1440 
1441   /* Pick up the alignment according to the mode or type.  */
1442   align = NDS32_MODE_TYPE_ALIGN (mode, type);
1443 
1444   return (align > PARM_BOUNDARY);
1445 }
1446 
1447 /* Return true if FUNC is a naked function.  */
1448 static bool
nds32_naked_function_p(tree func)1449 nds32_naked_function_p (tree func)
1450 {
1451   tree t;
1452 
1453   if (TREE_CODE (func) != FUNCTION_DECL)
1454     abort ();
1455 
1456   t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1457 
1458   return (t != NULL_TREE);
1459 }
1460 
1461 /* Function that check if 'X' is a valid address register.
1462    The variable 'STRICT' is very important to
1463    make decision for register number.
1464 
1465    STRICT : true
1466      => We are in reload pass or after reload pass.
1467         The register number should be strictly limited in general registers.
1468 
1469    STRICT : false
1470      => Before reload pass, we are free to use any register number.  */
1471 static bool
nds32_address_register_rtx_p(rtx x,bool strict)1472 nds32_address_register_rtx_p (rtx x, bool strict)
1473 {
1474   int regno;
1475 
1476   if (GET_CODE (x) != REG)
1477     return false;
1478 
1479   regno = REGNO (x);
1480 
1481   if (strict)
1482     return REGNO_OK_FOR_BASE_P (regno);
1483   else
1484     return true;
1485 }
1486 
1487 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1488 
1489    OUTER_MODE : Machine mode of outer address rtx.
1490         INDEX : Check if this rtx is valid to be a index for address.
1491        STRICT : If it is true, we are in reload pass or after reload pass.  */
1492 static bool
nds32_legitimate_index_p(enum machine_mode outer_mode,rtx index,bool strict)1493 nds32_legitimate_index_p (enum machine_mode outer_mode,
1494 			  rtx index,
1495 			  bool strict)
1496 {
1497   int regno;
1498   rtx op0;
1499   rtx op1;
1500 
1501   switch (GET_CODE (index))
1502     {
1503     case REG:
1504       regno = REGNO (index);
1505       /* If we are in reload pass or after reload pass,
1506          we need to limit it to general register.  */
1507       if (strict)
1508 	return REGNO_OK_FOR_INDEX_P (regno);
1509       else
1510 	return true;
1511 
1512     case CONST_INT:
1513       /* The alignment of the integer value is determined by 'outer_mode'.  */
1514       if (GET_MODE_SIZE (outer_mode) == 1)
1515 	{
1516 	  /* Further check if the value is legal for the 'outer_mode'.  */
1517 	  if (!satisfies_constraint_Is15 (index))
1518 	    return false;
1519 
1520 	  /* Pass all test, the value is valid, return true.  */
1521 	  return true;
1522 	}
1523       if (GET_MODE_SIZE (outer_mode) == 2
1524 	  && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1525 	{
1526 	  /* Further check if the value is legal for the 'outer_mode'.  */
1527 	  if (!satisfies_constraint_Is16 (index))
1528 	    return false;
1529 
1530 	  /* Pass all test, the value is valid, return true.  */
1531 	  return true;
1532 	}
1533       if (GET_MODE_SIZE (outer_mode) == 4
1534 	  && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1535 	{
1536 	  /* Further check if the value is legal for the 'outer_mode'.  */
1537 	  if (!satisfies_constraint_Is17 (index))
1538 	    return false;
1539 
1540 	  /* Pass all test, the value is valid, return true.  */
1541 	  return true;
1542 	}
1543       if (GET_MODE_SIZE (outer_mode) == 8
1544 	  && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1545 	{
1546 	  /* Further check if the value is legal for the 'outer_mode'.  */
1547 	  if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1548 							SImode)))
1549 	    return false;
1550 
1551 	  /* Pass all test, the value is valid, return true.  */
1552 	  return true;
1553 	}
1554 
1555       return false;
1556 
1557     case MULT:
1558       op0 = XEXP (index, 0);
1559       op1 = XEXP (index, 1);
1560 
1561       if (REG_P (op0) && CONST_INT_P (op1))
1562 	{
1563 	  int multiplier;
1564 	  multiplier = INTVAL (op1);
1565 
1566 	  /* We only allow (mult reg const_int_1)
1567 	     or (mult reg const_int_2) or (mult reg const_int_4).  */
1568 	  if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1569 	    return false;
1570 
1571 	  regno = REGNO (op0);
1572 	  /* Limit it in general registers if we are
1573 	     in reload pass or after reload pass.  */
1574 	  if(strict)
1575 	    return REGNO_OK_FOR_INDEX_P (regno);
1576 	  else
1577 	    return true;
1578 	}
1579 
1580       return false;
1581 
1582     case ASHIFT:
1583       op0 = XEXP (index, 0);
1584       op1 = XEXP (index, 1);
1585 
1586       if (REG_P (op0) && CONST_INT_P (op1))
1587 	{
1588 	  int sv;
1589 	  /* op1 is already the sv value for use to do left shift.  */
1590 	  sv = INTVAL (op1);
1591 
1592 	  /* We only allow (ashift reg const_int_0)
1593 	     or (ashift reg const_int_1) or (ashift reg const_int_2).  */
1594 	  if (sv != 0 && sv != 1 && sv !=2)
1595 	    return false;
1596 
1597 	  regno = REGNO (op0);
1598 	  /* Limit it in general registers if we are
1599 	     in reload pass or after reload pass.  */
1600 	  if(strict)
1601 	    return REGNO_OK_FOR_INDEX_P (regno);
1602 	  else
1603 	    return true;
1604 	}
1605 
1606       return false;
1607 
1608     default:
1609       return false;
1610     }
1611 }
1612 
1613 /* Function to expand builtin function for
1614    '[(unspec_volatile [(reg)])]'.  */
1615 static rtx
nds32_expand_builtin_null_ftype_reg(enum insn_code icode,tree exp,rtx target)1616 nds32_expand_builtin_null_ftype_reg (enum insn_code icode,
1617 				     tree exp, rtx target)
1618 {
1619   /* Mapping:
1620        ops[0] <--> value0 <--> arg0 */
1621   struct expand_operand ops[1];
1622   tree arg0;
1623   rtx value0;
1624 
1625   /* Grab the incoming arguments and extract its rtx.  */
1626   arg0 = CALL_EXPR_ARG (exp, 0);
1627   value0 = expand_normal (arg0);
1628 
1629   /* Create operands.  */
1630   create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
1631 
1632   /* Emit new instruction.  */
1633   if (!maybe_expand_insn (icode, 1, ops))
1634     error ("invalid argument to built-in function");
1635 
1636   return target;
1637 }
1638 
1639 /* Function to expand builtin function for
1640    '[(set (reg) (unspec_volatile [(imm)]))]'.  */
1641 static rtx
nds32_expand_builtin_reg_ftype_imm(enum insn_code icode,tree exp,rtx target)1642 nds32_expand_builtin_reg_ftype_imm (enum insn_code icode,
1643 				    tree exp, rtx target)
1644 {
1645   /* Mapping:
1646        ops[0] <--> target <--> exp
1647        ops[1] <--> value0 <--> arg0 */
1648   struct expand_operand ops[2];
1649   tree arg0;
1650   rtx value0;
1651 
1652   /* Grab the incoming arguments and extract its rtx.  */
1653   arg0 = CALL_EXPR_ARG (exp, 0);
1654   value0 = expand_normal (arg0);
1655 
1656   /* Create operands.  */
1657   create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
1658   create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0)));
1659 
1660   /* Emit new instruction.  */
1661   if (!maybe_expand_insn (icode, 2, ops))
1662     error ("invalid argument to built-in function");
1663 
1664   return target;
1665 }
1666 
1667 /* Function to expand builtin function for
1668    '[(unspec_volatile [(reg) (imm)])]' pattern.  */
1669 static rtx
nds32_expand_builtin_null_ftype_reg_imm(enum insn_code icode,tree exp,rtx target)1670 nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode,
1671 					 tree exp, rtx target)
1672 {
1673   /* Mapping:
1674        ops[0] <--> value0 <--> arg0
1675        ops[1] <--> value1 <--> arg1 */
1676   struct expand_operand ops[2];
1677   tree arg0, arg1;
1678   rtx value0, value1;
1679 
1680   /* Grab the incoming arguments and extract its rtx.  */
1681   arg0 = CALL_EXPR_ARG (exp, 0);
1682   arg1 = CALL_EXPR_ARG (exp, 1);
1683   value0 = expand_normal (arg0);
1684   value1 = expand_normal (arg1);
1685 
1686   /* Create operands.  */
1687   create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0)));
1688   create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1)));
1689 
1690   /* Emit new instruction.  */
1691   if (!maybe_expand_insn (icode, 2, ops))
1692     error ("invalid argument to built-in function");
1693 
1694   return target;
1695 }
1696 
1697 /* A helper function to return character based on byte size.  */
1698 static char
nds32_byte_to_size(int byte)1699 nds32_byte_to_size (int byte)
1700 {
1701   switch (byte)
1702     {
1703     case 4:
1704       return 'w';
1705     case 2:
1706       return 'h';
1707     case 1:
1708       return 'b';
1709     default:
1710       /* Normally it should not be here.  */
1711       gcc_unreachable ();
1712     }
1713 }
1714 
1715 /* A helper function to check if this function should contain prologue.  */
1716 static int
nds32_have_prologue_p(void)1717 nds32_have_prologue_p (void)
1718 {
1719   int i;
1720 
1721   for (i = 0; i < 28; i++)
1722     if (NDS32_REQUIRED_CALLEE_SAVED_P (i))
1723       return 1;
1724 
1725   return (flag_pic
1726 	  || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
1727 	  || NDS32_REQUIRED_CALLEE_SAVED_P (LP_REGNUM));
1728 }
1729 
1730 /* ------------------------------------------------------------------------ */
1731 
1732 /* PART 3: Implement target hook stuff definitions.  */
1733 
1734 /* Register Classes.  */
1735 
1736 static unsigned char
nds32_class_max_nregs(reg_class_t rclass ATTRIBUTE_UNUSED,enum machine_mode mode)1737 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1738 		       enum machine_mode mode)
1739 {
1740   /* Return the maximum number of consecutive registers
1741      needed to represent "mode" in a register of "rclass".  */
1742   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1743 }
1744 
1745 static int
nds32_register_priority(int hard_regno)1746 nds32_register_priority (int hard_regno)
1747 {
1748   /* Encourage to use r0-r7 for LRA when optimize for size.  */
1749   if (optimize_size && hard_regno < 8)
1750     return 4;
1751   return 3;
1752 }
1753 
1754 
1755 /* Stack Layout and Calling Conventions.  */
1756 
1757 /* There are three kinds of pointer concepts using in GCC compiler:
1758 
1759      frame pointer: A pointer to the first location of local variables.
1760      stack pointer: A pointer to the top of a stack frame.
1761      argument pointer: A pointer to the incoming arguments.
1762 
1763    In nds32 target calling convention, we are using 8-byte alignment.
1764    Besides, we would like to have each stack frame of a function includes:
1765 
1766      [Block A]
1767        1. previous hard frame pointer
1768        2. return address
1769        3. callee-saved registers
1770        4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1771                            and save it at
1772                            cfun->machine->callee_saved_area_padding_bytes)
1773 
1774      [Block B]
1775        1. local variables
1776        2. spilling location
1777        3. <padding bytes> (it will be calculated by GCC itself)
1778        4. incoming arguments
1779        5. <padding bytes> (it will be calculated by GCC itself)
1780 
1781      [Block C]
1782        1. <padding bytes> (it will be calculated by GCC itself)
1783        2. outgoing arguments
1784 
1785    We 'wrap' these blocks together with
1786    hard frame pointer ($r28) and stack pointer ($r31).
1787    By applying the basic frame/stack/argument pointers concept,
1788    the layout of a stack frame shoule be like this:
1789 
1790                             |    |
1791        old stack pointer ->  ----
1792                             |    | \
1793                             |    |   saved arguments for
1794                             |    |   vararg functions
1795                             |    | /
1796       hard frame pointer ->   --
1797       & argument pointer    |    | \
1798                             |    |   previous hardware frame pointer
1799                             |    |   return address
1800                             |    |   callee-saved registers
1801                             |    | /
1802            frame pointer ->   --
1803                             |    | \
1804                             |    |   local variables
1805                             |    |   and incoming arguments
1806                             |    | /
1807                               --
1808                             |    | \
1809                             |    |   outgoing
1810                             |    |   arguments
1811                             |    | /
1812            stack pointer ->  ----
1813 
1814   $SFP and $AP are used to represent frame pointer and arguments pointer,
1815   which will be both eliminated as hard frame pointer.  */
1816 
1817 /* -- Eliminating Frame Pointer and Arg Pointer.  */
1818 
nds32_can_eliminate(const int from_reg,const int to_reg)1819 static bool nds32_can_eliminate (const int from_reg, const int to_reg)
1820 {
1821   if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1822     return true;
1823 
1824   if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1825     return true;
1826 
1827   if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1828     return true;
1829 
1830   if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1831     return true;
1832 
1833   return false;
1834 }
1835 
1836 /* -- Passing Arguments in Registers.  */
1837 
1838 static rtx
nds32_function_arg(cumulative_args_t ca,enum machine_mode mode,const_tree type,bool named)1839 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1840 		    const_tree type, bool named)
1841 {
1842   CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1843 
1844   /* The last time this hook is called,
1845      it is called with MODE == VOIDmode.  */
1846   if (mode == VOIDmode)
1847     return NULL_RTX;
1848 
1849   /* For nameless arguments, they are passed on the stack.  */
1850   if (!named)
1851     return NULL_RTX;
1852 
1853   /* If there are still registers available, return it.  */
1854   if (NDS32_ARG_PASS_IN_REG_P (cum->reg_offset, mode, type))
1855     {
1856       /* Pick up the next available register number.  */
1857       unsigned int regno;
1858 
1859       regno = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type);
1860       return gen_rtx_REG (mode, regno);
1861     }
1862   else
1863     {
1864       /* No register available, return NULL_RTX.
1865          The compiler will use stack to pass argument instead.  */
1866       return NULL_RTX;
1867     }
1868 }
1869 
1870 static void
nds32_function_arg_advance(cumulative_args_t ca,enum machine_mode mode,const_tree type,bool named)1871 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1872 			    const_tree type, bool named)
1873 {
1874   CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1875 
1876   /* Advance next register for use.
1877      Only named argument could be advanced.  */
1878   if (named)
1879     {
1880       cum->reg_offset
1881 	= NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type)
1882 	  - NDS32_GPR_ARG_FIRST_REGNUM
1883 	  + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1884     }
1885 }
1886 
1887 static unsigned int
nds32_function_arg_boundary(enum machine_mode mode,const_tree type)1888 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1889 {
1890   return (nds32_needs_double_word_align (mode, type)
1891 	  ? NDS32_DOUBLE_WORD_ALIGNMENT
1892 	  : PARM_BOUNDARY);
1893 }
1894 
1895 /* -- How Scalar Function Values Are Returned.  */
1896 
1897 static rtx
nds32_function_value(const_tree ret_type,const_tree fn_decl_or_type ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)1898 nds32_function_value (const_tree ret_type,
1899 		      const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1900 		      bool outgoing ATTRIBUTE_UNUSED)
1901 {
1902   enum machine_mode mode;
1903   int unsignedp;
1904 
1905   mode = TYPE_MODE (ret_type);
1906   unsignedp = TYPE_UNSIGNED (ret_type);
1907 
1908   mode = promote_mode (ret_type, mode, &unsignedp);
1909 
1910   return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1911 }
1912 
1913 static rtx
nds32_libcall_value(enum machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)1914 nds32_libcall_value (enum machine_mode mode,
1915 		     const_rtx fun ATTRIBUTE_UNUSED)
1916 {
1917   return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1918 }
1919 
1920 static bool
nds32_function_value_regno_p(const unsigned int regno)1921 nds32_function_value_regno_p (const unsigned int regno)
1922 {
1923   return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1924 }
1925 
1926 /* -- Function Entry and Exit.  */
1927 
1928 /* The content produced from this function
1929    will be placed before prologue body.  */
1930 static void
nds32_asm_function_prologue(FILE * file,HOST_WIDE_INT size ATTRIBUTE_UNUSED)1931 nds32_asm_function_prologue (FILE *file,
1932 			     HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1933 {
1934   int r;
1935   const char *func_name;
1936   tree attrs;
1937   tree name;
1938 
1939   /* All stack frame information is supposed to be
1940      already computed when expanding prologue.
1941      The result is in cfun->machine.
1942      DO NOT call nds32_compute_stack_frame() here
1943      because it may corrupt the essential information.  */
1944 
1945   fprintf (file, "\t! BEGIN PROLOGUE\n");
1946   fprintf (file, "\t!     fp needed: %d\n", frame_pointer_needed);
1947   fprintf (file, "\t!  pretend_args: %d\n", cfun->machine->va_args_size);
1948   fprintf (file, "\t!    local_size: %d\n", cfun->machine->local_size);
1949   fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1950 
1951   /* Use df_regs_ever_live_p() to detect if the register
1952      is ever used in the current function.  */
1953   fprintf (file, "\t! registers ever_live: ");
1954   for (r = 0; r < 32; r++)
1955     {
1956       if (df_regs_ever_live_p (r))
1957 	fprintf (file, "%s, ", reg_names[r]);
1958     }
1959   fputc ('\n', file);
1960 
1961   /* Display the attributes of this function.  */
1962   fprintf (file, "\t! function attributes: ");
1963   /* Get the attributes tree list.
1964      Note that GCC builds attributes list with reverse order.  */
1965   attrs = DECL_ATTRIBUTES (current_function_decl);
1966 
1967   /* If there is no any attribute, print out "None".  */
1968   if (!attrs)
1969     fprintf (file, "None");
1970 
1971   /* If there are some attributes, try if we need to
1972      construct isr vector information.  */
1973   func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1974   nds32_construct_isr_vectors_information (attrs, func_name);
1975 
1976   /* Display all attributes of this function.  */
1977   while (attrs)
1978     {
1979       name = TREE_PURPOSE (attrs);
1980       fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1981 
1982       /* Pick up the next attribute.  */
1983       attrs = TREE_CHAIN (attrs);
1984     }
1985   fputc ('\n', file);
1986 }
1987 
1988 /* After rtl prologue has been expanded, this function is used.  */
1989 static void
nds32_asm_function_end_prologue(FILE * file)1990 nds32_asm_function_end_prologue (FILE *file)
1991 {
1992   fprintf (file, "\t! END PROLOGUE\n");
1993 
1994   /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1995      we can generate special directive: ".omit_fp_begin"
1996      to guide linker doing fp-as-gp optimization.
1997      However, for a naked function, which means
1998      it should not have prologue/epilogue,
1999      using fp-as-gp still requires saving $fp by push/pop behavior and
2000      there is no benefit to use fp-as-gp on such small function.
2001      So we need to make sure this function is NOT naked as well.  */
2002   if (!frame_pointer_needed
2003       && !cfun->machine->naked_p
2004       && cfun->machine->fp_as_gp_p)
2005     {
2006       fprintf (file, "\t! ----------------------------------------\n");
2007       fprintf (file, "\t! Guide linker to do "
2008 		     "link time optimization: fp-as-gp\n");
2009       fprintf (file, "\t! We add one more instruction to "
2010 		     "initialize $fp near to $gp location.\n");
2011       fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
2012       fprintf (file, "\t! this extra instruction should be "
2013 		     "eliminated at link stage.\n");
2014       fprintf (file, "\t.omit_fp_begin\n");
2015       fprintf (file, "\tla\t$fp,_FP_BASE_\n");
2016       fprintf (file, "\t! ----------------------------------------\n");
2017     }
2018 }
2019 
2020 /* Before rtl epilogue has been expanded, this function is used.  */
2021 static void
nds32_asm_function_begin_epilogue(FILE * file)2022 nds32_asm_function_begin_epilogue (FILE *file)
2023 {
2024   /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2025      we can generate special directive: ".omit_fp_end"
2026      to claim fp-as-gp optimization range.
2027      However, for a naked function,
2028      which means it should not have prologue/epilogue,
2029      using fp-as-gp still requires saving $fp by push/pop behavior and
2030      there is no benefit to use fp-as-gp on such small function.
2031      So we need to make sure this function is NOT naked as well.  */
2032   if (!frame_pointer_needed
2033       && !cfun->machine->naked_p
2034       && cfun->machine->fp_as_gp_p)
2035     {
2036       fprintf (file, "\t! ----------------------------------------\n");
2037       fprintf (file, "\t! Claim the range of fp-as-gp "
2038 		     "link time optimization\n");
2039       fprintf (file, "\t.omit_fp_end\n");
2040       fprintf (file, "\t! ----------------------------------------\n");
2041     }
2042 
2043   fprintf (file, "\t! BEGIN EPILOGUE\n");
2044 }
2045 
2046 /* The content produced from this function
2047    will be placed after epilogue body.  */
2048 static void
nds32_asm_function_epilogue(FILE * file,HOST_WIDE_INT size ATTRIBUTE_UNUSED)2049 nds32_asm_function_epilogue (FILE *file,
2050 			     HOST_WIDE_INT size ATTRIBUTE_UNUSED)
2051 {
2052   fprintf (file, "\t! END EPILOGUE\n");
2053 }
2054 
2055 static void
nds32_asm_output_mi_thunk(FILE * file,tree thunk ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,tree function)2056 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
2057 			   HOST_WIDE_INT delta,
2058 			   HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
2059 			   tree function)
2060 {
2061   int this_regno;
2062 
2063   /* Make sure unwind info is emitted for the thunk if needed.  */
2064   final_start_function (emit_barrier (), file, 1);
2065 
2066   this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
2067 		? 1
2068 		: 0);
2069 
2070   if (delta != 0)
2071     {
2072       if (satisfies_constraint_Is15 (GEN_INT (delta)))
2073 	{
2074 	  fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
2075 		   this_regno, this_regno, delta);
2076 	}
2077       else if (satisfies_constraint_Is20 (GEN_INT (delta)))
2078 	{
2079 	  fprintf (file, "\tmovi\t$ta, %ld\n", delta);
2080 	  fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2081 	}
2082       else
2083 	{
2084 	  fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
2085 	  fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
2086 	  fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2087 	}
2088     }
2089 
2090   fprintf (file, "\tb\t");
2091   assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
2092   fprintf (file, "\n");
2093 
2094   final_end_function ();
2095 }
2096 
2097 /* -- Permitting tail calls.  */
2098 
2099 /* Determine whether we need to enable warning for function return check.  */
2100 static bool
nds32_warn_func_return(tree decl)2101 nds32_warn_func_return (tree decl)
2102 {
2103 /* Naked functions are implemented entirely in assembly, including the
2104    return sequence, so suppress warnings about this.  */
2105   return !nds32_naked_function_p (decl);
2106 }
2107 
2108 
2109 /* Implementing the Varargs Macros.  */
2110 
2111 static bool
nds32_strict_argument_naming(cumulative_args_t ca ATTRIBUTE_UNUSED)2112 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
2113 {
2114   /* Return true so that all the named arguments for FUNCTION_ARG have named=1.
2115      If return false, for the variadic function, all named arguments EXCEPT
2116      the last are treated as named.  */
2117   return true;
2118 }
2119 
2120 
2121 /* Trampolines for Nested Functions.  */
2122 
2123 static void
nds32_asm_trampoline_template(FILE * f)2124 nds32_asm_trampoline_template (FILE *f)
2125 {
2126   if (TARGET_REDUCED_REGS)
2127     {
2128       /* Trampoline is not supported on reduced-set registers yet.  */
2129       sorry ("a nested function is not supported for reduced registers");
2130     }
2131   else
2132     {
2133       asm_fprintf (f, "\t! Trampoline code template\n");
2134       asm_fprintf (f, "\t! This code fragment will be copied "
2135 		      "into stack on demand\n");
2136 
2137       asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
2138       asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
2139 		      "! load nested function address\n");
2140       asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
2141 		      "! load chain_value\n");
2142       asm_fprintf (f, "\tjr\t$r15\n");
2143     }
2144 
2145   /* Preserve space ($pc + 16) for saving chain_value,
2146      nds32_trampoline_init will fill the value in this slot.  */
2147   asm_fprintf (f, "\t! space for saving chain_value\n");
2148   assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2149 
2150   /* Preserve space ($pc + 20) for saving nested function address,
2151      nds32_trampoline_init will fill the value in this slot.  */
2152   asm_fprintf (f, "\t! space for saving nested function address\n");
2153   assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2154 }
2155 
2156 /* Emit RTL insns to initialize the variable parts of a trampoline.  */
2157 static void
nds32_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)2158 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2159 {
2160   int i;
2161 
2162   /* Nested function address.  */
2163   rtx fnaddr;
2164   /* The memory rtx that is going to
2165      be filled with chain_value.  */
2166   rtx chain_value_mem;
2167   /* The memory rtx that is going to
2168      be filled with nested function address.  */
2169   rtx nested_func_mem;
2170 
2171   /* Start address of trampoline code in stack, for doing cache sync.  */
2172   rtx sync_cache_addr;
2173   /* Temporary register for sync instruction.  */
2174   rtx tmp_reg;
2175   /* Instruction-cache sync instruction,
2176      requesting an argument as starting address.  */
2177   rtx isync_insn;
2178   /* For convenience reason of doing comparison.  */
2179   int tramp_align_in_bytes;
2180 
2181   /* Trampoline is not supported on reduced-set registers yet.  */
2182   if (TARGET_REDUCED_REGS)
2183     sorry ("a nested function is not supported for reduced registers");
2184 
2185   /* STEP 1: Copy trampoline code template into stack,
2186              fill up essential data into stack.  */
2187 
2188   /* Extract nested function address rtx.  */
2189   fnaddr = XEXP (DECL_RTL (fndecl), 0);
2190 
2191   /* m_tramp is memory rtx that is going to be filled with trampoline code.
2192      We have nds32_asm_trampoline_template() to emit template pattern.  */
2193   emit_block_move (m_tramp, assemble_trampoline_template (),
2194 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2195 
2196   /* After copying trampoline code into stack,
2197      fill chain_value into stack.  */
2198   chain_value_mem = adjust_address (m_tramp, SImode, 16);
2199   emit_move_insn (chain_value_mem, chain_value);
2200   /* After copying trampoline code int stack,
2201      fill nested function address into stack.  */
2202   nested_func_mem = adjust_address (m_tramp, SImode, 20);
2203   emit_move_insn (nested_func_mem, fnaddr);
2204 
2205   /* STEP 2: Sync instruction-cache.  */
2206 
2207   /* We have successfully filled trampoline code into stack.
2208      However, in order to execute code in stack correctly,
2209      we must sync instruction cache.  */
2210   sync_cache_addr = XEXP (m_tramp, 0);
2211   tmp_reg         = gen_reg_rtx (SImode);
2212   isync_insn      = gen_unspec_volatile_isync (tmp_reg);
2213 
2214   /* Because nds32_cache_block_size is in bytes,
2215      we get trampoline alignment in bytes for convenient comparison.  */
2216   tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
2217 
2218   if (tramp_align_in_bytes >= nds32_cache_block_size
2219       && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
2220     {
2221       /* Under this condition, the starting address of trampoline
2222          must be aligned to the starting address of each cache block
2223          and we do not have to worry about cross-boundary issue.  */
2224       for (i = 0;
2225 	   i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2226 	       / nds32_cache_block_size;
2227 	   i++)
2228 	{
2229 	  emit_move_insn (tmp_reg,
2230 			  plus_constant (Pmode, sync_cache_addr,
2231 					 nds32_cache_block_size * i));
2232 	  emit_insn (isync_insn);
2233 	}
2234     }
2235   else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
2236     {
2237       /* The starting address of trampoline code
2238          may not be aligned to the cache block,
2239          so the trampoline code may be across two cache block.
2240          We need to sync the last element, which is 4-byte size,
2241          of trampoline template.  */
2242       for (i = 0;
2243 	   i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2244 	       / nds32_cache_block_size;
2245 	   i++)
2246 	{
2247 	  emit_move_insn (tmp_reg,
2248 			  plus_constant (Pmode, sync_cache_addr,
2249 					 nds32_cache_block_size * i));
2250 	  emit_insn (isync_insn);
2251 	}
2252 
2253       /* The last element of trampoline template is 4-byte size.  */
2254       emit_move_insn (tmp_reg,
2255 		      plus_constant (Pmode, sync_cache_addr,
2256 				     TRAMPOLINE_SIZE - 4));
2257       emit_insn (isync_insn);
2258     }
2259   else
2260     {
2261       /* This is the simplest case.
2262          Because TRAMPOLINE_SIZE is less than or
2263          equal to nds32_cache_block_size,
2264          we can just sync start address and
2265          the last element of trampoline code.  */
2266 
2267       /* Sync starting address of tampoline code.  */
2268       emit_move_insn (tmp_reg, sync_cache_addr);
2269       emit_insn (isync_insn);
2270       /* Sync the last element, which is 4-byte size,
2271          of trampoline template.  */
2272       emit_move_insn (tmp_reg,
2273 		      plus_constant (Pmode, sync_cache_addr,
2274 				     TRAMPOLINE_SIZE - 4));
2275       emit_insn (isync_insn);
2276     }
2277 
2278   /* Set instruction serialization barrier
2279      to guarantee the correct operations.  */
2280   emit_insn (gen_unspec_volatile_isb ());
2281 }
2282 
2283 
2284 /* Addressing Modes.  */
2285 
2286 static bool
nds32_legitimate_address_p(enum machine_mode mode,rtx x,bool strict)2287 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
2288 {
2289   /* For (mem:DI addr) or (mem:DF addr) case,
2290      we only allow 'addr' to be [reg], [symbol_ref],
2291                                 [const], or [reg + const_int] pattern.  */
2292   if (mode == DImode || mode == DFmode)
2293     {
2294       /* Allow [Reg + const_int] addressing mode.  */
2295       if (GET_CODE (x) == PLUS)
2296 	{
2297 	  if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2298 	      && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
2299 	      && CONST_INT_P (XEXP (x, 1)))
2300 	    return true;
2301 
2302 	  else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2303 		   && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
2304 		   && CONST_INT_P (XEXP (x, 0)))
2305 	    return true;
2306 	}
2307 
2308       /* Now check [reg], [symbol_ref], and [const].  */
2309       if (GET_CODE (x) != REG
2310 	  && GET_CODE (x) != SYMBOL_REF
2311 	  && GET_CODE (x) != CONST)
2312 	return false;
2313     }
2314 
2315   /* Check if 'x' is a valid address.  */
2316   switch (GET_CODE (x))
2317     {
2318     case REG:
2319       /* (mem (reg A)) => [Ra] */
2320       return nds32_address_register_rtx_p (x, strict);
2321 
2322     case SYMBOL_REF:
2323 
2324       if (!TARGET_GP_DIRECT
2325 	  && (reload_completed
2326 	      || reload_in_progress
2327 	      || lra_in_progress))
2328 	return false;
2329 
2330       /* (mem (symbol_ref A)) => [symbol_ref] */
2331       return !currently_expanding_to_rtl;
2332 
2333     case CONST:
2334 
2335       if (!TARGET_GP_DIRECT
2336 	  && (reload_completed
2337 	      || reload_in_progress
2338 	      || lra_in_progress))
2339 	return false;
2340 
2341       /* (mem (const (...)))
2342          => [ + const_addr ], where const_addr = symbol_ref + const_int */
2343       if (GET_CODE (XEXP (x, 0)) == PLUS)
2344 	{
2345 	  rtx plus_op = XEXP (x, 0);
2346 
2347 	  rtx op0 = XEXP (plus_op, 0);
2348 	  rtx op1 = XEXP (plus_op, 1);
2349 
2350 	  if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
2351 	    return true;
2352 	  else
2353 	    return false;
2354 	}
2355 
2356 	return false;
2357 
2358     case POST_MODIFY:
2359       /* (mem (post_modify (reg) (plus (reg) (reg))))
2360          => [Ra], Rb */
2361       /* (mem (post_modify (reg) (plus (reg) (const_int))))
2362          => [Ra], const_int */
2363       if (GET_CODE (XEXP (x, 0)) == REG
2364 	  && GET_CODE (XEXP (x, 1)) == PLUS)
2365 	{
2366 	  rtx plus_op = XEXP (x, 1);
2367 
2368 	  rtx op0 = XEXP (plus_op, 0);
2369 	  rtx op1 = XEXP (plus_op, 1);
2370 
2371 	  if (nds32_address_register_rtx_p (op0, strict)
2372 	      && nds32_legitimate_index_p (mode, op1, strict))
2373 	    return true;
2374 	  else
2375 	    return false;
2376 	}
2377 
2378 	return false;
2379 
2380     case POST_INC:
2381     case POST_DEC:
2382       /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2383       /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2384       /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2385          We only need to deal with register Ra.  */
2386       if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2387 	return true;
2388       else
2389 	return false;
2390 
2391     case PLUS:
2392       /* (mem (plus reg const_int))
2393          => [Ra + imm] */
2394       /* (mem (plus reg reg))
2395          => [Ra + Rb] */
2396       /* (mem (plus (mult reg const_int) reg))
2397          => [Ra + Rb << sv] */
2398       if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2399 	  && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2400 	return true;
2401       else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2402 	       && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2403 	return true;
2404       else
2405 	return false;
2406 
2407     case LO_SUM:
2408       if (!TARGET_GP_DIRECT)
2409 	return true;
2410 
2411     default:
2412       return false;
2413     }
2414 }
2415 
2416 
2417 /* Describing Relative Costs of Operations.  */
2418 
nds32_register_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t from,reg_class_t to)2419 static int nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2420 				     reg_class_t from,
2421 				     reg_class_t to)
2422 {
2423   if (from == HIGH_REGS || to == HIGH_REGS)
2424     return 6;
2425 
2426   return 2;
2427 }
2428 
nds32_memory_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t rclass ATTRIBUTE_UNUSED,bool in ATTRIBUTE_UNUSED)2429 static int nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2430 				   reg_class_t rclass ATTRIBUTE_UNUSED,
2431 				   bool in ATTRIBUTE_UNUSED)
2432 {
2433   return 8;
2434 }
2435 
2436 /* This target hook describes the relative costs of RTL expressions.
2437    Return 'true' when all subexpressions of x have been processed.
2438    Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2439    Refer to gcc/rtlanal.c for more information.  */
2440 static bool
nds32_rtx_costs(rtx x,int code,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed)2441 nds32_rtx_costs (rtx x,
2442 		 int code,
2443 		 int outer_code,
2444 		 int opno ATTRIBUTE_UNUSED,
2445 		 int *total,
2446 		 bool speed)
2447 {
2448   /* According to 'speed', goto suitable cost model section.  */
2449   if (speed)
2450     goto performance_cost;
2451   else
2452     goto size_cost;
2453 
2454 
2455 performance_cost:
2456   /* This is section for performance cost model.  */
2457 
2458   /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
2459      We treat it as 4-cycle cost for each instruction
2460      under performance consideration.  */
2461   switch (code)
2462     {
2463     case SET:
2464       /* For 'SET' rtx, we need to return false
2465          so that it can recursively calculate costs.  */
2466       return false;
2467 
2468     case USE:
2469       /* Used in combine.c as a marker.  */
2470       *total = 0;
2471       break;
2472 
2473     case MULT:
2474       *total = COSTS_N_INSNS (1);
2475       break;
2476 
2477     case DIV:
2478     case UDIV:
2479     case MOD:
2480     case UMOD:
2481       *total = COSTS_N_INSNS (7);
2482       break;
2483 
2484     default:
2485       *total = COSTS_N_INSNS (1);
2486       break;
2487     }
2488 
2489   return true;
2490 
2491 
2492 size_cost:
2493   /* This is section for size cost model.  */
2494 
2495   /* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
2496      We treat it as 4-byte cost for each instruction
2497      under code size consideration.  */
2498   switch (code)
2499     {
2500     case SET:
2501       /* For 'SET' rtx, we need to return false
2502          so that it can recursively calculate costs.  */
2503       return false;
2504 
2505     case USE:
2506       /* Used in combine.c as a marker.  */
2507       *total = 0;
2508       break;
2509 
2510     case CONST_INT:
2511       /* All instructions involving constant operation
2512          need to be considered for cost evaluation.  */
2513       if (outer_code == SET)
2514 	{
2515 	  /* (set X imm5s), use movi55, 2-byte cost.
2516 	     (set X imm20s), use movi, 4-byte cost.
2517 	     (set X BIG_INT), use sethi/ori, 8-byte cost.  */
2518 	  if (satisfies_constraint_Is05 (x))
2519 	    *total = COSTS_N_INSNS (1) - 2;
2520 	  else if (satisfies_constraint_Is20 (x))
2521 	    *total = COSTS_N_INSNS (1);
2522 	  else
2523 	    *total = COSTS_N_INSNS (2);
2524 	}
2525       else if (outer_code == PLUS || outer_code == MINUS)
2526 	{
2527 	  /* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
2528 	     General case, cost 1 instruction with 4-byte.  */
2529 	  if (satisfies_constraint_Iu05 (x))
2530 	    *total = COSTS_N_INSNS (1) - 2;
2531 	  else
2532 	    *total = COSTS_N_INSNS (1);
2533 	}
2534       else if (outer_code == ASHIFT)
2535 	{
2536 	  /* Possible slli333, 2-byte cost.
2537 	     General case, cost 1 instruction with 4-byte.  */
2538 	  if (satisfies_constraint_Iu03 (x))
2539 	    *total = COSTS_N_INSNS (1) - 2;
2540 	  else
2541 	    *total = COSTS_N_INSNS (1);
2542 	}
2543       else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
2544 	{
2545 	  /* Possible srai45 or srli45, 2-byte cost.
2546 	     General case, cost 1 instruction with 4-byte.  */
2547 	  if (satisfies_constraint_Iu05 (x))
2548 	    *total = COSTS_N_INSNS (1) - 2;
2549 	  else
2550 	    *total = COSTS_N_INSNS (1);
2551 	}
2552       else
2553 	{
2554 	  /* For other cases, simply set it 4-byte cost.  */
2555 	  *total = COSTS_N_INSNS (1);
2556 	}
2557       break;
2558 
2559     case CONST_DOUBLE:
2560       /* It requires high part and low part processing, set it 8-byte cost.  */
2561       *total = COSTS_N_INSNS (2);
2562       break;
2563 
2564     default:
2565       /* For other cases, generally we set it 4-byte cost
2566          and stop resurively traversing.  */
2567       *total = COSTS_N_INSNS (1);
2568       break;
2569     }
2570 
2571   return true;
2572 }
2573 
nds32_address_cost(rtx address,enum machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed)2574 static int nds32_address_cost (rtx address,
2575 			       enum machine_mode mode ATTRIBUTE_UNUSED,
2576 			       addr_space_t as ATTRIBUTE_UNUSED,
2577 			       bool speed)
2578 {
2579   rtx plus0, plus1;
2580   enum rtx_code code;
2581 
2582   code = GET_CODE (address);
2583 
2584   /* According to 'speed', goto suitable cost model section.  */
2585   if (speed)
2586     goto performance_cost;
2587   else
2588     goto size_cost;
2589 
2590 performance_cost:
2591   /* This is section for performance cost model.  */
2592 
2593   /* FALLTHRU, currently we use same cost model as size_cost.  */
2594 
2595 size_cost:
2596   /* This is section for size cost model.  */
2597 
2598   switch (code)
2599     {
2600     case POST_MODIFY:
2601     case POST_INC:
2602     case POST_DEC:
2603       /* We encourage that rtx contains
2604          POST_MODIFY/POST_INC/POST_DEC behavior.  */
2605       return 0;
2606 
2607     case SYMBOL_REF:
2608       /* We can have gp-relative load/store for symbol_ref.
2609          Have it 4-byte cost.  */
2610       return COSTS_N_INSNS (1);
2611 
2612     case CONST:
2613       /* It is supposed to be the pattern (const (plus symbol_ref const_int)).
2614          Have it 4-byte cost.  */
2615       return COSTS_N_INSNS (1);
2616 
2617     case REG:
2618       /* Simply return 4-byte costs.  */
2619       return COSTS_N_INSNS (1);
2620 
2621     case PLUS:
2622       /* We do not need to check if the address is a legitimate address,
2623          because this hook is never called with an invalid address.
2624          But we better check the range of
2625          const_int value for cost, if it exists.  */
2626       plus0 = XEXP (address, 0);
2627       plus1 = XEXP (address, 1);
2628 
2629       if (REG_P (plus0) && CONST_INT_P (plus1))
2630         {
2631 	  /* If it is possible to be lwi333/swi333 form,
2632 	     make it 2-byte cost.  */
2633 	  if (satisfies_constraint_Iu05 (plus1))
2634 	    return (COSTS_N_INSNS (1) - 2);
2635 	  else
2636 	    return COSTS_N_INSNS (1);
2637 	}
2638 
2639       /* For other 'plus' situation, make it cost 4-byte.  */
2640       return COSTS_N_INSNS (1);
2641 
2642     default:
2643       break;
2644     }
2645 
2646   return COSTS_N_INSNS (4);
2647 }
2648 
2649 
2650 /* Defining the Output Assembler Language.  */
2651 
2652 /* -- The Overall Framework of an Assembler File.  */
2653 
2654 static void
nds32_asm_file_start(void)2655 nds32_asm_file_start (void)
2656 {
2657   int i;
2658 
2659   default_file_start ();
2660 
2661   /* Tell assembler which ABI we are using.  */
2662   fprintf (asm_out_file, "\t! ABI version\n");
2663   fprintf (asm_out_file, "\t.abi_2\n");
2664 
2665   /* Tell assembler that this asm code is generated by compiler.  */
2666   fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2667   fprintf (asm_out_file, "\t.flag\tverbatim\n");
2668   /* Give assembler the size of each vector for interrupt handler.  */
2669   fprintf (asm_out_file, "\t! This vector size directive is required "
2670 			 "for checking inconsistency on interrupt handler\n");
2671   fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2672 
2673   /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2674      the compiler may produce 'la $fp,_FP_BASE_' instruction
2675      at prologue for fp-as-gp optimization.
2676      We should emit weak reference of _FP_BASE_ to avoid undefined reference
2677      in case user does not pass '--relax' option to linker.  */
2678   if (TARGET_FORCE_FP_AS_GP || optimize_size)
2679     {
2680       fprintf (asm_out_file, "\t! This weak reference is required to do "
2681 			     "fp-as-gp link time optimization\n");
2682       fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2683     }
2684   /* If user enables '-mex9', we should emit relaxation directive
2685      to tell linker that this file is allowed to do ex9 optimization.  */
2686   if (TARGET_EX9)
2687     {
2688       fprintf (asm_out_file, "\t! This relaxation directive is required "
2689 			     "to do ex9 link time optimization\n");
2690       fprintf (asm_out_file, "\t.relax\tex9\n");
2691     }
2692 
2693   fprintf (asm_out_file, "\t! ------------------------------------\n");
2694 
2695   if (TARGET_ISA_V2)
2696     fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2697   if (TARGET_ISA_V3)
2698     fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2699   if (TARGET_ISA_V3M)
2700     fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2701 
2702   fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2703 			 ((TARGET_BIG_ENDIAN) ? "big-endian"
2704 					      : "little-endian"));
2705 
2706   fprintf (asm_out_file, "\t! ------------------------------------\n");
2707 
2708   fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2709 			 ((TARGET_CMOV) ? "Yes"
2710 					: "No"));
2711   fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2712 			 ((TARGET_PERF_EXT) ? "Yes"
2713 					    : "No"));
2714 
2715   fprintf (asm_out_file, "\t! ------------------------------------\n");
2716 
2717   fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2718 			 ((TARGET_V3PUSH) ? "Yes"
2719 					  : "No"));
2720   fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2721 			 ((TARGET_16_BIT) ? "Yes"
2722 					  : "No"));
2723   fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2724 			 ((TARGET_GP_DIRECT) ? "Yes"
2725 					     : "No"));
2726   fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2727 			 ((TARGET_REDUCED_REGS) ? "Yes"
2728 						: "No"));
2729 
2730   fprintf (asm_out_file, "\t! ------------------------------------\n");
2731 
2732   if (optimize_size)
2733     fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2734   else
2735     fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2736 
2737   fprintf (asm_out_file, "\t! ------------------------------------\n");
2738 
2739   fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2740 			 nds32_cache_block_size);
2741 
2742   fprintf (asm_out_file, "\t! ------------------------------------\n");
2743 
2744   /* Initialize isr vector information array before compiling functions.  */
2745   for (i = 0; i < NDS32_N_ISR_VECTORS; i++)
2746     {
2747       nds32_isr_vectors[i].category = NDS32_ISR_NONE;
2748       strcpy (nds32_isr_vectors[i].func_name, "");
2749       nds32_isr_vectors[i].save_reg = NDS32_PARTIAL_SAVE;
2750       nds32_isr_vectors[i].nested_type = NDS32_NOT_NESTED;
2751       nds32_isr_vectors[i].total_n_vectors = 0;
2752       strcpy (nds32_isr_vectors[i].nmi_name, "");
2753       strcpy (nds32_isr_vectors[i].warm_name, "");
2754     }
2755 }
2756 
2757 static void
nds32_asm_file_end(void)2758 nds32_asm_file_end (void)
2759 {
2760   int i;
2761 
2762   /* If all the vectors are NDS32_ISR_NONE, we can return immediately.  */
2763   for (i = 0; i < NDS32_N_ISR_VECTORS; i++)
2764     if (nds32_isr_vectors[i].category != NDS32_ISR_NONE)
2765       break;
2766 
2767   if (i == NDS32_N_ISR_VECTORS)
2768     return;
2769 
2770   /* At least one vector is NOT NDS32_ISR_NONE,
2771      we should output isr vector information.  */
2772   fprintf (asm_out_file, "\t! ------------------------------------\n");
2773   fprintf (asm_out_file, "\t! The isr vector information:\n");
2774   fprintf (asm_out_file, "\t! ------------------------------------\n");
2775 
2776   /* Check reset handler first.  Its vector number is always 0.  */
2777   if (nds32_isr_vectors[0].category == NDS32_ISR_RESET)
2778     {
2779       nds32_emit_isr_reset_content ();
2780       fprintf (asm_out_file, "\t! ------------------------------------\n");
2781     }
2782 
2783   /* Check other vectors, starting from vector number 1.  */
2784   for (i = 1; i < NDS32_N_ISR_VECTORS; i++)
2785     {
2786       if (nds32_isr_vectors[i].category == NDS32_ISR_INTERRUPT
2787 	  || nds32_isr_vectors[i].category == NDS32_ISR_EXCEPTION)
2788 	{
2789 	  /* Found one vector which is interupt or exception.
2790 	     Output its jmptbl and vector section content.  */
2791 	  fprintf (asm_out_file, "\t! interrupt/exception vector %02d\n", i);
2792 	  fprintf (asm_out_file, "\t! ------------------------------------\n");
2793 	  nds32_emit_isr_jmptbl_section (i);
2794 	  fprintf (asm_out_file, "\t! ....................................\n");
2795 	  nds32_emit_isr_vector_section (i);
2796 	  fprintf (asm_out_file, "\t! ------------------------------------\n");
2797 	}
2798     }
2799 
2800   fprintf (asm_out_file, "\t! ------------------------------------\n");
2801 }
2802 
2803 /* -- Output and Generation of Labels.  */
2804 
2805 static void
nds32_asm_globalize_label(FILE * stream,const char * name)2806 nds32_asm_globalize_label (FILE *stream, const char *name)
2807 {
2808   fputs ("\t.global\t", stream);
2809   assemble_name (stream, name);
2810   fputs ("\n", stream);
2811 }
2812 
2813 /* -- Output of Assembler Instructions.  */
2814 
2815 static void
nds32_print_operand(FILE * stream,rtx x,int code)2816 nds32_print_operand (FILE *stream, rtx x, int code)
2817 {
2818   int op_value;
2819 
2820   switch (code)
2821     {
2822     case 0 :
2823       /* Do nothing special.  */
2824       break;
2825 
2826     case 'V':
2827       /* 'x' is supposed to be CONST_INT, get the value.  */
2828       gcc_assert (CONST_INT_P (x));
2829       op_value = INTVAL (x);
2830 
2831       /* According to the Andes architecture,
2832          the system/user register index range is 0 ~ 1023.
2833          In order to avoid conflict between user-specified-integer value
2834          and enum-specified-register value,
2835          the 'enum nds32_intrinsic_registers' value
2836          in nds32_intrinsic.h starts from 1024.  */
2837       if (op_value < 1024 && op_value >= 0)
2838 	{
2839 	  /* If user gives integer value directly (0~1023),
2840 	     we just print out the value.  */
2841 	  fprintf (stream, "%d", op_value);
2842 	}
2843       else if (op_value < 0
2844 	       || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2845 			       + 1024))
2846 	{
2847 	  /* The enum index value for array size is out of range.  */
2848 	  error ("intrinsic register index is out of range");
2849 	}
2850       else
2851 	{
2852 	  /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2853 	     we can print out register name.  Remember to substract 1024.  */
2854 	  fprintf (stream, "%s",
2855 			   nds32_intrinsic_register_names[op_value - 1024]);
2856 	}
2857 
2858       /* No need to handle following process, so return immediately.  */
2859       return;
2860 
2861     default :
2862       /* Unknown flag.  */
2863       output_operand_lossage ("invalid operand output code");
2864       break;
2865     }
2866 
2867   switch (GET_CODE (x))
2868     {
2869     case LABEL_REF:
2870     case SYMBOL_REF:
2871       output_addr_const (stream, x);
2872       break;
2873 
2874     case REG:
2875       /* Forbid using static chain register ($r16)
2876          on reduced-set registers configuration.  */
2877       if (TARGET_REDUCED_REGS
2878 	  && REGNO (x) == STATIC_CHAIN_REGNUM)
2879 	sorry ("a nested function is not supported for reduced registers");
2880 
2881       /* Normal cases, print out register name.  */
2882       fputs (reg_names[REGNO (x)], stream);
2883       break;
2884 
2885     case MEM:
2886       output_address (XEXP (x, 0));
2887       break;
2888 
2889     case CODE_LABEL:
2890     case CONST_INT:
2891     case CONST:
2892       output_addr_const (stream, x);
2893       break;
2894 
2895     default:
2896       /* Generally, output_addr_const () is able to handle most cases.
2897          We want to see what CODE could appear,
2898          so we use gcc_unreachable() to stop it.  */
2899       debug_rtx (x);
2900       gcc_unreachable ();
2901       break;
2902     }
2903 }
2904 
2905 static void
nds32_print_operand_address(FILE * stream,rtx x)2906 nds32_print_operand_address (FILE *stream, rtx x)
2907 {
2908   rtx op0, op1;
2909 
2910   switch (GET_CODE (x))
2911     {
2912     case SYMBOL_REF:
2913     case CONST:
2914       /* [ + symbol_ref] */
2915       /* [ + const_addr], where const_addr = symbol_ref + const_int */
2916       fputs ("[ + ", stream);
2917       output_addr_const (stream, x);
2918       fputs ("]", stream);
2919       break;
2920 
2921     case REG:
2922       /* Forbid using static chain register ($r16)
2923          on reduced-set registers configuration.  */
2924       if (TARGET_REDUCED_REGS
2925 	  && REGNO (x) == STATIC_CHAIN_REGNUM)
2926 	sorry ("a nested function is not supported for reduced registers");
2927 
2928       /* [Ra] */
2929       fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2930       break;
2931 
2932     case PLUS:
2933       op0 = XEXP (x, 0);
2934       op1 = XEXP (x, 1);
2935 
2936       /* Checking op0, forbid using static chain register ($r16)
2937          on reduced-set registers configuration.  */
2938       if (TARGET_REDUCED_REGS
2939 	  && REG_P (op0)
2940 	  && REGNO (op0) == STATIC_CHAIN_REGNUM)
2941 	sorry ("a nested function is not supported for reduced registers");
2942       /* Checking op1, forbid using static chain register ($r16)
2943          on reduced-set registers configuration.  */
2944       if (TARGET_REDUCED_REGS
2945 	  && REG_P (op1)
2946 	  && REGNO (op1) == STATIC_CHAIN_REGNUM)
2947 	sorry ("a nested function is not supported for reduced registers");
2948 
2949       if (REG_P (op0) && CONST_INT_P (op1))
2950 	{
2951 	  /* [Ra + imm] */
2952 	  fprintf (stream, "[%s + (%d)]",
2953 			   reg_names[REGNO (op0)], (int)INTVAL (op1));
2954 	}
2955       else if (REG_P (op0) && REG_P (op1))
2956 	{
2957 	  /* [Ra + Rb] */
2958 	  fprintf (stream, "[%s + %s]",
2959 			   reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2960 	}
2961       else if (GET_CODE (op0) == MULT && REG_P (op1))
2962 	{
2963 	  /* [Ra + Rb << sv]
2964 	     From observation, the pattern looks like:
2965 	     (plus:SI (mult:SI (reg:SI 58)
2966 	                       (const_int 4 [0x4]))
2967 	              (reg/f:SI 57)) */
2968 	  int sv;
2969 
2970 	  /* We need to set sv to output shift value.  */
2971 	  if (INTVAL (XEXP (op0, 1)) == 1)
2972 	    sv = 0;
2973 	  else if (INTVAL (XEXP (op0, 1)) == 2)
2974 	    sv = 1;
2975 	  else if (INTVAL (XEXP (op0, 1)) == 4)
2976 	    sv = 2;
2977 	  else
2978 	    gcc_unreachable ();
2979 
2980 	  fprintf (stream, "[%s + %s << %d]",
2981 			   reg_names[REGNO (op1)],
2982 			   reg_names[REGNO (XEXP (op0, 0))],
2983 			   sv);
2984 	}
2985       else
2986 	{
2987 	  /* The control flow is not supposed to be here.  */
2988 	  debug_rtx (x);
2989 	  gcc_unreachable ();
2990 	}
2991 
2992       break;
2993 
2994     case POST_MODIFY:
2995       /* (post_modify (regA) (plus (regA) (regB)))
2996          (post_modify (regA) (plus (regA) (const_int)))
2997          We would like to extract
2998          regA and regB (or const_int) from plus rtx.  */
2999       op0 = XEXP (XEXP (x, 1), 0);
3000       op1 = XEXP (XEXP (x, 1), 1);
3001 
3002       /* Checking op0, forbid using static chain register ($r16)
3003          on reduced-set registers configuration.  */
3004       if (TARGET_REDUCED_REGS
3005 	  && REG_P (op0)
3006 	  && REGNO (op0) == STATIC_CHAIN_REGNUM)
3007 	sorry ("a nested function is not supported for reduced registers");
3008       /* Checking op1, forbid using static chain register ($r16)
3009          on reduced-set registers configuration.  */
3010       if (TARGET_REDUCED_REGS
3011 	  && REG_P (op1)
3012 	  && REGNO (op1) == STATIC_CHAIN_REGNUM)
3013 	sorry ("a nested function is not supported for reduced registers");
3014 
3015       if (REG_P (op0) && REG_P (op1))
3016 	{
3017 	  /* [Ra], Rb */
3018 	  fprintf (stream, "[%s], %s",
3019 			   reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
3020 	}
3021       else if (REG_P (op0) && CONST_INT_P (op1))
3022 	{
3023 	  /* [Ra], imm */
3024 	  fprintf (stream, "[%s], %d",
3025 			   reg_names[REGNO (op0)], (int)INTVAL (op1));
3026 	}
3027       else
3028 	{
3029 	  /* The control flow is not supposed to be here.  */
3030 	  debug_rtx (x);
3031 	  gcc_unreachable ();
3032 	}
3033 
3034       break;
3035 
3036     case POST_INC:
3037     case POST_DEC:
3038       op0 = XEXP (x, 0);
3039 
3040       /* Checking op0, forbid using static chain register ($r16)
3041          on reduced-set registers configuration.  */
3042       if (TARGET_REDUCED_REGS
3043 	  && REG_P (op0)
3044 	  && REGNO (op0) == STATIC_CHAIN_REGNUM)
3045 	sorry ("a nested function is not supported for reduced registers");
3046 
3047       if (REG_P (op0))
3048 	{
3049 	  /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3050 	     The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3051 	     We only need to deal with register Ra.  */
3052 	  fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
3053 	}
3054       else
3055 	{
3056 	  /* The control flow is not supposed to be here.  */
3057 	  debug_rtx (x);
3058 	  gcc_unreachable ();
3059 	}
3060 
3061       break;
3062 
3063     default :
3064       /* Generally, output_addr_const () is able to handle most cases.
3065          We want to see what CODE could appear,
3066          so we use gcc_unreachable() to stop it.  */
3067       debug_rtx (x);
3068       gcc_unreachable ();
3069       break;
3070     }
3071 }
3072 
3073 
3074 /* Defining target-specific uses of __attribute__.  */
3075 
3076 /* Add some checking after merging attributes.  */
3077 static tree
nds32_merge_decl_attributes(tree olddecl,tree newdecl)3078 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
3079 {
3080   tree combined_attrs;
3081 
3082   /* Create combined attributes.  */
3083   combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
3084 				     DECL_ATTRIBUTES (newdecl));
3085 
3086   /* Since newdecl is acutally a duplicate of olddecl,
3087      we can take olddecl for some operations.  */
3088   if (TREE_CODE (olddecl) == FUNCTION_DECL)
3089     {
3090       /* Check isr-specific attributes conflict.  */
3091       nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
3092     }
3093 
3094   return combined_attrs;
3095 }
3096 
3097 /* Add some checking when inserting attributes.  */
3098 static void
nds32_insert_attributes(tree decl,tree * attributes)3099 nds32_insert_attributes (tree decl, tree *attributes)
3100 {
3101   /* For function declaration, we need to check isr-specific attributes:
3102        1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3103        2. Check valid integer value for interrupt/exception.
3104        3. Check valid integer value for reset.
3105        4. Check valid function for nmi/warm.  */
3106   if (TREE_CODE (decl) == FUNCTION_DECL)
3107     {
3108       tree func_attrs;
3109       tree intr, excp, reset;
3110 
3111       /* Pick up function attributes.  */
3112       func_attrs = *attributes;
3113 
3114       /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict.  */
3115       nds32_check_isr_attrs_conflict (decl, func_attrs);
3116 
3117       /* Now we are starting to check valid id value
3118          for interrupt/exception/reset.
3119          Note that we ONLY check its validity here.
3120          To construct isr vector information, it is still performed
3121          by nds32_construct_isr_vectors_information().  */
3122       intr  = lookup_attribute ("interrupt", func_attrs);
3123       excp  = lookup_attribute ("exception", func_attrs);
3124       reset = lookup_attribute ("reset", func_attrs);
3125 
3126       if (intr || excp)
3127 	{
3128 	  /* Deal with interrupt/exception.  */
3129 	  tree id_list;
3130 	  unsigned int lower_bound, upper_bound;
3131 
3132 	  /* The way to handle interrupt or exception is the same,
3133 	     we just need to take care of actual vector number.
3134 	     For interrupt(0..63), the actual vector number is (9..72).
3135 	     For exception(1..8), the actual vector number is (1..8).  */
3136 	  lower_bound = (intr) ? (0) : (1);
3137 	  upper_bound = (intr) ? (63) : (8);
3138 
3139 	  /* Prepare id list so that we can traverse id value.  */
3140 	  id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
3141 
3142 	  /* 2. Check valid integer value for interrupt/exception.  */
3143 	  while (id_list)
3144 	    {
3145 	      tree id;
3146 
3147 	      /* Pick up each vector id value.  */
3148 	      id = TREE_VALUE (id_list);
3149 	      /* Issue error if it is not a valid integer value.  */
3150 	      if (TREE_CODE (id) != INTEGER_CST
3151 		  || TREE_INT_CST_LOW (id) < lower_bound
3152 		  || TREE_INT_CST_LOW (id) > upper_bound)
3153 		error ("invalid id value for interrupt/exception attribute");
3154 
3155 	      /* Advance to next id.  */
3156 	      id_list = TREE_CHAIN (id_list);
3157 	    }
3158 	}
3159       else if (reset)
3160 	{
3161 	  /* Deal with reset.  */
3162 	  tree id_list;
3163 	  tree id;
3164 	  tree nmi, warm;
3165 	  unsigned int lower_bound;
3166 	  unsigned int upper_bound;
3167 
3168 	  /* Prepare id_list and identify id value so that
3169 	     we can check if total number of vectors is valid.  */
3170 	  id_list = TREE_VALUE (reset);
3171 	  id = TREE_VALUE (id_list);
3172 
3173 	  /* The maximum numbers for user's interrupt is 64.  */
3174 	  lower_bound = 0;
3175 	  upper_bound = 64;
3176 
3177 	  /* 3. Check valid integer value for reset.  */
3178 	  if (TREE_CODE (id) != INTEGER_CST
3179 	      || TREE_INT_CST_LOW (id) < lower_bound
3180 	      || TREE_INT_CST_LOW (id) > upper_bound)
3181 	    error ("invalid id value for reset attribute");
3182 
3183 	  /* 4. Check valid function for nmi/warm.  */
3184 	  nmi  = lookup_attribute ("nmi", func_attrs);
3185 	  warm = lookup_attribute ("warm", func_attrs);
3186 
3187 	  if (nmi != NULL_TREE)
3188 	    {
3189 	      tree nmi_func_list;
3190 	      tree nmi_func;
3191 
3192 	      nmi_func_list = TREE_VALUE (nmi);
3193 	      nmi_func = TREE_VALUE (nmi_func_list);
3194 
3195 	      /* Issue error if it is not a valid nmi function.  */
3196 	      if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
3197 		error ("invalid nmi function for reset attribute");
3198 	    }
3199 
3200 	  if (warm != NULL_TREE)
3201 	    {
3202 	      tree warm_func_list;
3203 	      tree warm_func;
3204 
3205 	      warm_func_list = TREE_VALUE (warm);
3206 	      warm_func = TREE_VALUE (warm_func_list);
3207 
3208 	      /* Issue error if it is not a valid warm function.  */
3209 	      if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
3210 		error ("invalid warm function for reset attribute");
3211 	    }
3212 	}
3213       else
3214 	{
3215 	  /* No interrupt, exception, or reset attribute is set.  */
3216 	  return;
3217 	}
3218     }
3219 }
3220 
3221 static bool
nds32_option_pragma_parse(tree args ATTRIBUTE_UNUSED,tree pop_target ATTRIBUTE_UNUSED)3222 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
3223 			   tree pop_target ATTRIBUTE_UNUSED)
3224 {
3225   /* Currently, we do not parse any pragma target by ourself,
3226      so just simply return false.  */
3227   return false;
3228 }
3229 
3230 static void
nds32_option_override(void)3231 nds32_option_override (void)
3232 {
3233   /* After all the command options have been parsed,
3234      we shall deal with some flags for changing compiler settings.  */
3235 
3236   /* At first, we check if we have to strictly
3237      set some flags based on ISA family.  */
3238   if (TARGET_ISA_V2)
3239     {
3240       /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH.  */
3241       target_flags &= ~MASK_V3PUSH;
3242     }
3243   if (TARGET_ISA_V3)
3244     {
3245       /* Under V3 ISA, currently nothing should be strictly set.  */
3246     }
3247   if (TARGET_ISA_V3M)
3248     {
3249       /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS.  */
3250       target_flags |= MASK_REDUCED_REGS;
3251       /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT.  */
3252       target_flags &= ~MASK_PERF_EXT;
3253     }
3254 
3255   /* See if we are using reduced-set registers:
3256        $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
3257      If so, we must forbid using $r11~$r14, $r16~$r27.  */
3258   if (TARGET_REDUCED_REGS)
3259     {
3260       int r;
3261 
3262       /* Prevent register allocator from
3263          choosing it as doing register allocation.  */
3264       for (r = 11; r <= 14; r++)
3265 	fixed_regs[r] = call_used_regs[r] = 1;
3266       for (r = 16; r <= 27; r++)
3267 	fixed_regs[r] = call_used_regs[r] = 1;
3268     }
3269 
3270   /* See if user explicitly would like to use fp-as-gp optimization.
3271      If so, we must prevent $fp from being allocated
3272      during register allocation.  */
3273   if (TARGET_FORCE_FP_AS_GP)
3274     fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
3275 
3276   if (!TARGET_16_BIT)
3277     {
3278       /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH.  */
3279       target_flags &= ~MASK_V3PUSH;
3280     }
3281 
3282   /* Currently, we don't support PIC code generation yet.  */
3283   if (flag_pic)
3284     sorry ("not support -fpic");
3285 }
3286 
3287 
3288 /* Miscellaneous Parameters.  */
3289 
3290 static void
nds32_init_builtins(void)3291 nds32_init_builtins (void)
3292 {
3293   tree pointer_type_node  = build_pointer_type (integer_type_node);
3294 
3295   tree void_ftype_void    = build_function_type (void_type_node,
3296 						 void_list_node);
3297 
3298   tree void_ftype_pint    = build_function_type_list (void_type_node,
3299 						      pointer_type_node,
3300 						      NULL_TREE);
3301 
3302   tree int_ftype_int      = build_function_type_list (integer_type_node,
3303 						      integer_type_node,
3304 						      NULL_TREE);
3305 
3306   tree void_ftype_int_int = build_function_type_list (void_type_node,
3307 						      integer_type_node,
3308 						      integer_type_node,
3309 						      NULL_TREE);
3310 
3311   /* Cache.  */
3312   add_builtin_function ("__builtin_nds32_isync",  void_ftype_pint,
3313 			NDS32_BUILTIN_ISYNC,
3314 			BUILT_IN_MD, NULL, NULL_TREE);
3315   add_builtin_function ("__builtin_nds32_isb",  void_ftype_void,
3316 			NDS32_BUILTIN_ISB,
3317 			BUILT_IN_MD, NULL, NULL_TREE);
3318 
3319   /* Register Transfer.  */
3320   add_builtin_function ("__builtin_nds32_mfsr",  int_ftype_int,
3321 			NDS32_BUILTIN_MFSR,
3322 			BUILT_IN_MD, NULL, NULL_TREE);
3323   add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int,
3324 			NDS32_BUILTIN_MFUSR,
3325 			BUILT_IN_MD, NULL, NULL_TREE);
3326   add_builtin_function ("__builtin_nds32_mtsr",  void_ftype_int_int,
3327 			NDS32_BUILTIN_MTSR,
3328 			BUILT_IN_MD, NULL, NULL_TREE);
3329   add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int,
3330 			NDS32_BUILTIN_MTUSR,
3331 			BUILT_IN_MD, NULL, NULL_TREE);
3332 
3333   /* Interrupt.  */
3334   add_builtin_function ("__builtin_nds32_setgie_en",  void_ftype_void,
3335 			NDS32_BUILTIN_SETGIE_EN,
3336 			BUILT_IN_MD, NULL, NULL_TREE);
3337   add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void,
3338 			NDS32_BUILTIN_SETGIE_DIS,
3339 			BUILT_IN_MD, NULL, NULL_TREE);
3340 }
3341 
3342 static rtx
nds32_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)3343 nds32_expand_builtin (tree exp,
3344 		      rtx target,
3345 		      rtx subtarget ATTRIBUTE_UNUSED,
3346 		      enum machine_mode mode ATTRIBUTE_UNUSED,
3347 		      int ignore ATTRIBUTE_UNUSED)
3348 {
3349   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3350 
3351   int fcode = DECL_FUNCTION_CODE (fndecl);
3352 
3353   switch (fcode)
3354     {
3355     /* Cache.  */
3356     case NDS32_BUILTIN_ISYNC:
3357       return nds32_expand_builtin_null_ftype_reg
3358 	     (CODE_FOR_unspec_volatile_isync, exp, target);
3359     case NDS32_BUILTIN_ISB:
3360       /* Since there are no result and operands for isb instruciton,
3361          we can simply emit this rtx.  */
3362       emit_insn (gen_unspec_volatile_isb ());
3363       return target;
3364 
3365     /* Register Transfer.  */
3366     case NDS32_BUILTIN_MFSR:
3367       return nds32_expand_builtin_reg_ftype_imm
3368 	     (CODE_FOR_unspec_volatile_mfsr, exp, target);
3369     case NDS32_BUILTIN_MFUSR:
3370       return nds32_expand_builtin_reg_ftype_imm
3371 	     (CODE_FOR_unspec_volatile_mfusr, exp, target);
3372     case NDS32_BUILTIN_MTSR:
3373       return nds32_expand_builtin_null_ftype_reg_imm
3374 	     (CODE_FOR_unspec_volatile_mtsr, exp, target);
3375     case NDS32_BUILTIN_MTUSR:
3376       return nds32_expand_builtin_null_ftype_reg_imm
3377 	     (CODE_FOR_unspec_volatile_mtusr, exp, target);
3378 
3379     /* Interrupt.  */
3380     case NDS32_BUILTIN_SETGIE_EN:
3381       /* Since there are no result and operands for setgie.e instruciton,
3382          we can simply emit this rtx.  */
3383       emit_insn (gen_unspec_volatile_setgie_en ());
3384       return target;
3385     case NDS32_BUILTIN_SETGIE_DIS:
3386       /* Since there are no result and operands for setgie.d instruciton,
3387          we can simply emit this rtx.  */
3388       emit_insn (gen_unspec_volatile_setgie_dis ());
3389       return target;
3390 
3391     default:
3392       gcc_unreachable ();
3393     }
3394 
3395   return NULL_RTX;
3396 }
3397 
3398 
3399 /* ------------------------------------------------------------------------ */
3400 
3401 /* PART 4: Implemet extern function definitions,
3402            the prototype is in nds32-protos.h.  */
3403 
3404 /* Defining Data Structures for Per-function Information.  */
3405 
3406 void
nds32_init_expanders(void)3407 nds32_init_expanders (void)
3408 {
3409   /* Arrange to initialize and mark the machine per-function status.  */
3410   init_machine_status = nds32_init_machine_status;
3411 }
3412 
3413 
3414 /* Register Usage.  */
3415 
3416 /* -- How Values Fit in Registers.  */
3417 
3418 int
nds32_hard_regno_nregs(int regno ATTRIBUTE_UNUSED,enum machine_mode mode)3419 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
3420 			enum machine_mode mode)
3421 {
3422   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
3423 }
3424 
3425 int
nds32_hard_regno_mode_ok(int regno,enum machine_mode mode)3426 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
3427 {
3428   /* Restrict double-word quantities to even register pairs.  */
3429   if (HARD_REGNO_NREGS (regno, mode) == 1
3430       || !((regno) & 1))
3431     return 1;
3432 
3433   return 0;
3434 }
3435 
3436 
3437 /* Register Classes.  */
3438 
3439 enum reg_class
nds32_regno_reg_class(int regno)3440 nds32_regno_reg_class (int regno)
3441 {
3442   /* Refer to nds32.h for more register class details.  */
3443 
3444   if (regno >= 0 && regno <= 7)
3445     return LOW_REGS;
3446   else if (regno >= 8 && regno <= 11)
3447     return MIDDLE_REGS;
3448   else if (regno >= 12 && regno <= 14)
3449     return HIGH_REGS;
3450   else if (regno == 15)
3451     return R15_TA_REG;
3452   else if (regno >= 16 && regno <= 19)
3453     return MIDDLE_REGS;
3454   else if (regno >= 20 && regno <= 31)
3455     return HIGH_REGS;
3456   else if (regno == 32 || regno == 33)
3457     return FRAME_REGS;
3458   else
3459     return NO_REGS;
3460 }
3461 
3462 
3463 /* Stack Layout and Calling Conventions.  */
3464 
3465 /* -- Basic Stack Layout.  */
3466 
3467 rtx
nds32_return_addr_rtx(int count,rtx frameaddr ATTRIBUTE_UNUSED)3468 nds32_return_addr_rtx (int count,
3469 		       rtx frameaddr ATTRIBUTE_UNUSED)
3470 {
3471   /* There is no way to determine the return address
3472      if frameaddr is the frame that has 'count' steps
3473      up from current frame.  */
3474   if (count != 0)
3475     return NULL_RTX;
3476 
3477   /* If count == 0, it means we are at current frame,
3478      the return address is $r30 ($lp).  */
3479   return get_hard_reg_initial_val (Pmode, LP_REGNUM);
3480 }
3481 
3482 /* -- Eliminating Frame Pointer and Arg Pointer.  */
3483 
3484 HOST_WIDE_INT
nds32_initial_elimination_offset(unsigned int from_reg,unsigned int to_reg)3485 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
3486 {
3487   HOST_WIDE_INT offset;
3488 
3489   /* Compute and setup stack frame size.
3490      The result will be in cfun->machine.  */
3491   nds32_compute_stack_frame ();
3492 
3493   /* Remember to consider
3494      cfun->machine->callee_saved_area_padding_bytes
3495      when calculating offset.  */
3496   if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
3497     {
3498       offset = (cfun->machine->fp_size
3499 	        + cfun->machine->gp_size
3500 		+ cfun->machine->lp_size
3501 		+ cfun->machine->callee_saved_regs_size
3502 		+ cfun->machine->callee_saved_area_padding_bytes
3503 		+ cfun->machine->local_size
3504 		+ cfun->machine->out_args_size);
3505     }
3506   else if (from_reg == ARG_POINTER_REGNUM
3507 	   && to_reg == HARD_FRAME_POINTER_REGNUM)
3508     {
3509       offset = 0;
3510     }
3511   else if (from_reg == FRAME_POINTER_REGNUM
3512 	   && to_reg == STACK_POINTER_REGNUM)
3513     {
3514       offset = (cfun->machine->local_size + cfun->machine->out_args_size);
3515     }
3516   else if (from_reg == FRAME_POINTER_REGNUM
3517 	   && to_reg == HARD_FRAME_POINTER_REGNUM)
3518     {
3519       offset = (-1) * (cfun->machine->fp_size
3520 		       + cfun->machine->gp_size
3521 		       + cfun->machine->lp_size
3522 		       + cfun->machine->callee_saved_regs_size
3523 		       + cfun->machine->callee_saved_area_padding_bytes);
3524     }
3525   else
3526     {
3527       gcc_unreachable ();
3528     }
3529 
3530   return offset;
3531 }
3532 
3533 /* -- Passing Arguments in Registers.  */
3534 
3535 void
nds32_init_cumulative_args(CUMULATIVE_ARGS * cum,tree fntype ATTRIBUTE_UNUSED,rtx libname ATTRIBUTE_UNUSED,tree fndecl ATTRIBUTE_UNUSED,int n_named_args ATTRIBUTE_UNUSED)3536 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
3537 			    tree fntype ATTRIBUTE_UNUSED,
3538 			    rtx libname ATTRIBUTE_UNUSED,
3539 			    tree fndecl ATTRIBUTE_UNUSED,
3540 			    int n_named_args ATTRIBUTE_UNUSED)
3541 {
3542   /* Initial available registers
3543      (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
3544      for passing arguments.  */
3545   cum->reg_offset = 0;
3546 }
3547 
3548 /* -- Function Entry and Exit.  */
3549 
3550 /* Function for normal multiple push prologue.  */
3551 void
nds32_expand_prologue(void)3552 nds32_expand_prologue (void)
3553 {
3554   int fp_adjust;
3555   int sp_adjust;
3556   int en4_const;
3557 
3558   rtx Rb, Re;
3559   rtx push_insn;
3560   rtx fp_adjust_insn, sp_adjust_insn;
3561 
3562   /* Before computing everything for stack frame size,
3563      we check if it is still worth to use fp_as_gp optimization.
3564      If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
3565      so that $fp will be saved on stack.  */
3566   cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
3567 
3568   /* Compute and setup stack frame size.
3569      The result will be in cfun->machine.  */
3570   nds32_compute_stack_frame ();
3571 
3572   /* If the function is 'naked',
3573      we do not have to generate prologue code fragment.  */
3574   if (cfun->machine->naked_p)
3575     return;
3576 
3577   /* Get callee_first_regno and callee_last_regno.  */
3578   Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3579   Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3580 
3581   /* push_insn = gen_stack_push_multiple(first_regno, last_regno),
3582      the pattern 'stack_push_multiple' is implemented in nds32.md.
3583      For En4 field, we have to calculate its constant value.
3584      Refer to Andes ISA for more information.  */
3585   en4_const = 0;
3586   if (cfun->machine->fp_size)
3587     en4_const += 8;
3588   if (cfun->machine->gp_size)
3589     en4_const += 4;
3590   if (cfun->machine->lp_size)
3591     en4_const += 2;
3592 
3593   /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3594      to be saved, we don't have to create multiple push instruction.
3595      Otherwise, a multiple push instruction is needed.  */
3596   if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3597     {
3598       /* Create multiple push instruction rtx.  */
3599       push_insn = nds32_gen_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
3600       /* Emit rtx into instructions list and receive INSN rtx form.  */
3601       push_insn = emit_insn (push_insn);
3602 
3603       /* The insn rtx 'push_insn' will change frame layout.
3604          We need to use RTX_FRAME_RELATED_P so that GCC is able to
3605          generate CFI (Call Frame Information) stuff.  */
3606       RTX_FRAME_RELATED_P (push_insn) = 1;
3607     }
3608 
3609   /* Check frame_pointer_needed to see
3610      if we shall emit fp adjustment instruction.  */
3611   if (frame_pointer_needed)
3612     {
3613       /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
3614                           + (4 * callee-saved-registers)
3615          Note: No need to adjust
3616                cfun->machine->callee_saved_area_padding_bytes,
3617                because, at this point, stack pointer is just
3618                at the position after push instruction.  */
3619       fp_adjust = cfun->machine->fp_size
3620 		  + cfun->machine->gp_size
3621 		  + cfun->machine->lp_size
3622 		  + cfun->machine->callee_saved_regs_size;
3623       fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3624 				   stack_pointer_rtx,
3625 				   GEN_INT (fp_adjust));
3626       /* Emit rtx into instructions list and receive INSN rtx form.  */
3627       fp_adjust_insn = emit_insn (fp_adjust_insn);
3628     }
3629 
3630   /* Adjust $sp = $sp - local_size - out_args_size
3631                       - callee_saved_area_padding_bytes.  */
3632   sp_adjust = cfun->machine->local_size
3633 	      + cfun->machine->out_args_size
3634 	      + cfun->machine->callee_saved_area_padding_bytes;
3635   /* sp_adjust value may be out of range of the addi instruction,
3636      create alternative add behavior with TA_REGNUM if necessary,
3637      using NEGATIVE value to tell that we are decreasing address.  */
3638   sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3639   if (sp_adjust)
3640     {
3641       /* Generate sp adjustment instruction if and only if sp_adjust != 0.  */
3642       sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3643 				   stack_pointer_rtx,
3644 				   GEN_INT (-1 * sp_adjust));
3645       /* Emit rtx into instructions list and receive INSN rtx form.  */
3646       sp_adjust_insn = emit_insn (sp_adjust_insn);
3647 
3648       /* The insn rtx 'sp_adjust_insn' will change frame layout.
3649          We need to use RTX_FRAME_RELATED_P so that GCC is able to
3650          generate CFI (Call Frame Information) stuff.  */
3651       RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3652     }
3653 
3654   /* Prevent the instruction scheduler from
3655      moving instructions across the boundary.  */
3656   emit_insn (gen_blockage ());
3657 }
3658 
3659 /* Function for normal multiple pop epilogue.  */
3660 void
nds32_expand_epilogue(void)3661 nds32_expand_epilogue (void)
3662 {
3663   int sp_adjust;
3664   int en4_const;
3665 
3666   rtx Rb, Re;
3667   rtx pop_insn;
3668   rtx sp_adjust_insn;
3669 
3670   /* Compute and setup stack frame size.
3671      The result will be in cfun->machine.  */
3672   nds32_compute_stack_frame ();
3673 
3674   /* Prevent the instruction scheduler from
3675      moving instructions across the boundary.  */
3676   emit_insn (gen_blockage ());
3677 
3678   /* If the function is 'naked', we do not have to generate
3679      epilogue code fragment BUT 'ret' instruction.  */
3680   if (cfun->machine->naked_p)
3681     {
3682       /* Generate return instruction by using
3683          unspec_volatile_func_return pattern.
3684          Make sure this instruction is after gen_blockage().
3685          NOTE that $lp will become 'live'
3686          after this instruction has been emitted.  */
3687       emit_insn (gen_unspec_volatile_func_return ());
3688       return;
3689     }
3690 
3691   if (frame_pointer_needed)
3692     {
3693       /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3694                           - (4 * callee-saved-registers)
3695          Note: No need to adjust
3696                cfun->machine->callee_saved_area_padding_bytes,
3697                because we want to adjust stack pointer
3698                to the position for pop instruction.  */
3699       sp_adjust = cfun->machine->fp_size
3700 		  + cfun->machine->gp_size
3701 		  + cfun->machine->lp_size
3702 		  + cfun->machine->callee_saved_regs_size;
3703       sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3704 				   hard_frame_pointer_rtx,
3705 				   GEN_INT (-1 * sp_adjust));
3706       /* Emit rtx into instructions list and receive INSN rtx form.  */
3707       sp_adjust_insn = emit_insn (sp_adjust_insn);
3708     }
3709   else
3710     {
3711       /* If frame pointer is NOT needed,
3712          we cannot calculate the sp adjustment from frame pointer.
3713          Instead, we calculate the adjustment by local_size,
3714          out_args_size, and callee_saved_area_padding_bytes.
3715          Notice that such sp adjustment value may be out of range,
3716          so we have to deal with it as well.  */
3717 
3718       /* Adjust $sp = $sp + local_size + out_args_size
3719                           + callee_saved_area_padding_bytes.  */
3720       sp_adjust = cfun->machine->local_size
3721 		  + cfun->machine->out_args_size
3722 		  + cfun->machine->callee_saved_area_padding_bytes;
3723       /* sp_adjust value may be out of range of the addi instruction,
3724          create alternative add behavior with TA_REGNUM if necessary,
3725          using POSITIVE value to tell that we are increasing address.  */
3726       sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3727       if (sp_adjust)
3728 	{
3729 	  /* Generate sp adjustment instruction
3730 	     if and only if sp_adjust != 0.  */
3731 	  sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3732 				       stack_pointer_rtx,
3733 				       GEN_INT (sp_adjust));
3734 	  /* Emit rtx into instructions list and receive INSN rtx form.  */
3735 	  sp_adjust_insn = emit_insn (sp_adjust_insn);
3736 	}
3737     }
3738 
3739   /* Get callee_first_regno and callee_last_regno.  */
3740   Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3741   Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3742 
3743   /* pop_insn = gen_stack_pop_multiple(first_regno, last_regno),
3744      the pattern 'stack_pop_multiple' is implementad in nds32.md.
3745      For En4 field, we have to calculate its constant value.
3746      Refer to Andes ISA for more information.  */
3747   en4_const = 0;
3748   if (cfun->machine->fp_size)
3749     en4_const += 8;
3750   if (cfun->machine->gp_size)
3751     en4_const += 4;
3752   if (cfun->machine->lp_size)
3753     en4_const += 2;
3754 
3755   /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3756      to be saved, we don't have to create multiple pop instruction.
3757      Otherwise, a multiple pop instruction is needed.  */
3758   if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3759     {
3760       /* Create multiple pop instruction rtx.  */
3761       pop_insn = nds32_gen_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3762       /* Emit pop instruction.  */
3763       emit_insn (pop_insn);
3764     }
3765 
3766   /* Generate return instruction by using
3767      unspec_volatile_func_return pattern.  */
3768   emit_insn (gen_unspec_volatile_func_return ());
3769 }
3770 
3771 /* Function for v3push prologue.  */
3772 void
nds32_expand_prologue_v3push(void)3773 nds32_expand_prologue_v3push (void)
3774 {
3775   int fp_adjust;
3776   int sp_adjust;
3777 
3778   rtx Rb, Re;
3779   rtx push_insn;
3780   rtx fp_adjust_insn, sp_adjust_insn;
3781 
3782   /* Before computing everything for stack frame size,
3783      we check if it is still worth to use fp_as_gp optimization.
3784      If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
3785      so that $fp will be saved on stack.  */
3786   cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
3787 
3788   /* Compute and setup stack frame size.
3789      The result will be in cfun->machine.  */
3790   nds32_compute_stack_frame ();
3791 
3792   /* If the function is 'naked',
3793      we do not have to generate prologue code fragment.  */
3794   if (cfun->machine->naked_p)
3795     return;
3796 
3797   /* Get callee_first_regno and callee_last_regno.  */
3798   Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3799   Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3800 
3801   /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3802      where imm8u has to be 8-byte alignment.  */
3803   sp_adjust = cfun->machine->local_size
3804 	      + cfun->machine->out_args_size
3805 	      + cfun->machine->callee_saved_area_padding_bytes;
3806 
3807   if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3808       && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3809     {
3810       /* We can use 'push25 Re,imm8u'.  */
3811 
3812       /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
3813          the pattern 'stack_v3push' is implemented in nds32.md.
3814          The (const_int 14) means v3push always push { $fp $gp $lp }.  */
3815       push_insn = nds32_gen_stack_v3push (Rb, Re,
3816 					  GEN_INT (14), GEN_INT (sp_adjust));
3817       /* emit rtx into instructions list and receive INSN rtx form */
3818       push_insn = emit_insn (push_insn);
3819 
3820       /* The insn rtx 'push_insn' will change frame layout.
3821          We need to use RTX_FRAME_RELATED_P so that GCC is able to
3822          generate CFI (Call Frame Information) stuff.  */
3823       RTX_FRAME_RELATED_P (push_insn) = 1;
3824 
3825       /* Check frame_pointer_needed to see
3826          if we shall emit fp adjustment instruction.  */
3827       if (frame_pointer_needed)
3828 	{
3829 	  /* adjust $fp = $sp   + 4         ($fp size)
3830 	                        + 4         ($gp size)
3831 	                        + 4         ($lp size)
3832 	                        + (4 * n)   (callee-saved registers)
3833 	                        + sp_adjust ('push25 Re,imm8u')
3834 	     Note: Since we use 'push25 Re,imm8u',
3835 	           the position of stack pointer is further
3836 	           changed after push instruction.
3837 	           Hence, we need to take sp_adjust value
3838 	           into consideration.  */
3839 	  fp_adjust = cfun->machine->fp_size
3840 		      + cfun->machine->gp_size
3841 		      + cfun->machine->lp_size
3842 		      + cfun->machine->callee_saved_regs_size
3843 		      + sp_adjust;
3844 	  fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3845 				       stack_pointer_rtx,
3846 				       GEN_INT (fp_adjust));
3847 	  /* Emit rtx into instructions list and receive INSN rtx form.  */
3848 	  fp_adjust_insn = emit_insn (fp_adjust_insn);
3849 	}
3850     }
3851   else
3852     {
3853       /* We have to use 'push25 Re,0' and
3854          expand one more instruction to adjust $sp later.  */
3855 
3856       /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
3857          the pattern 'stack_v3push' is implemented in nds32.md.
3858          The (const_int 14) means v3push always push { $fp $gp $lp }.  */
3859       push_insn = nds32_gen_stack_v3push (Rb, Re,
3860 					  GEN_INT (14), GEN_INT (0));
3861       /* Emit rtx into instructions list and receive INSN rtx form.  */
3862       push_insn = emit_insn (push_insn);
3863 
3864       /* The insn rtx 'push_insn' will change frame layout.
3865          We need to use RTX_FRAME_RELATED_P so that GCC is able to
3866          generate CFI (Call Frame Information) stuff.  */
3867       RTX_FRAME_RELATED_P (push_insn) = 1;
3868 
3869       /* Check frame_pointer_needed to see
3870          if we shall emit fp adjustment instruction.  */
3871       if (frame_pointer_needed)
3872 	{
3873 	  /* adjust $fp = $sp + 4        ($fp size)
3874 	                      + 4        ($gp size)
3875 	                      + 4        ($lp size)
3876 	                      + (4 * n)  (callee-saved registers)
3877 	     Note: Since we use 'push25 Re,0',
3878 	           the stack pointer is just at the position
3879 	           after push instruction.
3880 	           No need to take sp_adjust into consideration.  */
3881 	  fp_adjust = cfun->machine->fp_size
3882 		      + cfun->machine->gp_size
3883 		      + cfun->machine->lp_size
3884 		      + cfun->machine->callee_saved_regs_size;
3885 	  fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3886 				       stack_pointer_rtx,
3887 				       GEN_INT (fp_adjust));
3888 	  /* Emit rtx into instructions list and receive INSN rtx form.  */
3889 	  fp_adjust_insn = emit_insn (fp_adjust_insn);
3890 	}
3891 
3892       /* Because we use 'push25 Re,0',
3893          we need to expand one more instruction to adjust $sp.
3894          However, sp_adjust value may be out of range of the addi instruction,
3895          create alternative add behavior with TA_REGNUM if necessary,
3896          using NEGATIVE value to tell that we are decreasing address.  */
3897       sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3898       if (sp_adjust)
3899 	{
3900 	  /* Generate sp adjustment instruction
3901 	     if and only if sp_adjust != 0.  */
3902 	  sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3903 				       stack_pointer_rtx,
3904 				       GEN_INT (-1 * sp_adjust));
3905 	  /* Emit rtx into instructions list and receive INSN rtx form.  */
3906 	  sp_adjust_insn = emit_insn (sp_adjust_insn);
3907 
3908 	  /* The insn rtx 'sp_adjust_insn' will change frame layout.
3909 	     We need to use RTX_FRAME_RELATED_P so that GCC is able to
3910 	     generate CFI (Call Frame Information) stuff.  */
3911 	  RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3912 	}
3913     }
3914 
3915   /* Prevent the instruction scheduler from
3916      moving instructions across the boundary.  */
3917   emit_insn (gen_blockage ());
3918 }
3919 
3920 /* Function for v3pop epilogue.  */
3921 void
nds32_expand_epilogue_v3pop(void)3922 nds32_expand_epilogue_v3pop (void)
3923 {
3924   int sp_adjust;
3925 
3926   rtx Rb, Re;
3927   rtx pop_insn;
3928   rtx sp_adjust_insn;
3929 
3930   /* Compute and setup stack frame size.
3931      The result will be in cfun->machine.  */
3932   nds32_compute_stack_frame ();
3933 
3934   /* Prevent the instruction scheduler from
3935      moving instructions across the boundary.  */
3936   emit_insn (gen_blockage ());
3937 
3938   /* If the function is 'naked', we do not have to generate
3939      epilogue code fragment BUT 'ret' instruction.  */
3940   if (cfun->machine->naked_p)
3941     {
3942       /* Generate return instruction by using
3943          unspec_volatile_func_return pattern.
3944          Make sure this instruction is after gen_blockage().
3945          NOTE that $lp will become 'live'
3946          after this instruction has been emitted.  */
3947       emit_insn (gen_unspec_volatile_func_return ());
3948       return;
3949     }
3950 
3951   /* Get callee_first_regno and callee_last_regno.  */
3952   Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3953   Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3954 
3955   /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3956      where imm8u has to be 8-byte alignment.  */
3957   sp_adjust = cfun->machine->local_size
3958 	      + cfun->machine->out_args_size
3959 	      + cfun->machine->callee_saved_area_padding_bytes;
3960 
3961   /* We have to consider alloca issue as well.
3962      If the function does call alloca(), the stack pointer is not fixed.
3963      In that case, we cannot use 'pop25 Re,imm8u' directly.
3964      We have to caculate stack pointer from frame pointer
3965      and then use 'pop25 Re,0'.
3966      Of course, the frame_pointer_needed should be nonzero
3967      if the function calls alloca().  */
3968   if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3969       && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3970       && !cfun->calls_alloca)
3971     {
3972       /* We can use 'pop25 Re,imm8u'.  */
3973 
3974       /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
3975          the pattern 'stack_v3pop' is implementad in nds32.md.
3976          The (const_int 14) means v3pop always pop { $fp $gp $lp }.  */
3977       pop_insn = nds32_gen_stack_v3pop (Rb, Re,
3978 					GEN_INT (14), GEN_INT (sp_adjust));
3979 
3980       /* Emit pop instruction.  */
3981       emit_insn (pop_insn);
3982     }
3983   else
3984     {
3985       /* We have to use 'pop25 Re,0', and prior to it,
3986          we must expand one more instruction to adjust $sp.  */
3987 
3988       if (frame_pointer_needed)
3989 	{
3990 	  /* adjust $sp = $fp - 4        ($fp size)
3991 	                      - 4        ($gp size)
3992 	                      - 4        ($lp size)
3993 	                      - (4 * n)  (callee-saved registers)
3994 	     Note: No need to adjust
3995 	           cfun->machine->callee_saved_area_padding_bytes,
3996 	           because we want to adjust stack pointer
3997 	           to the position for pop instruction.  */
3998 	  sp_adjust = cfun->machine->fp_size
3999 		      + cfun->machine->gp_size
4000 		      + cfun->machine->lp_size
4001 		      + cfun->machine->callee_saved_regs_size;
4002 	  sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
4003 				       hard_frame_pointer_rtx,
4004 				       GEN_INT (-1 * sp_adjust));
4005 	  /* Emit rtx into instructions list and receive INSN rtx form.  */
4006 	  sp_adjust_insn = emit_insn (sp_adjust_insn);
4007 	}
4008       else
4009 	{
4010 	  /* If frame pointer is NOT needed,
4011 	     we cannot calculate the sp adjustment from frame pointer.
4012 	     Instead, we calculate the adjustment by local_size,
4013 	     out_args_size, and callee_saved_area_padding_bytes.
4014 	     Notice that such sp adjustment value may be out of range,
4015 	     so we have to deal with it as well.  */
4016 
4017 	  /* Adjust $sp = $sp + local_size + out_args_size
4018 			      + callee_saved_area_padding_bytes.  */
4019 	  sp_adjust = cfun->machine->local_size
4020 		      + cfun->machine->out_args_size
4021 		      + cfun->machine->callee_saved_area_padding_bytes;
4022 	  /* sp_adjust value may be out of range of the addi instruction,
4023 	     create alternative add behavior with TA_REGNUM if necessary,
4024 	     using POSITIVE value to tell that we are increasing address.  */
4025 	  sp_adjust = nds32_force_addi_stack_int (sp_adjust);
4026 	  if (sp_adjust)
4027 	    {
4028 	      /* Generate sp adjustment instruction
4029 	         if and only if sp_adjust != 0.  */
4030 	      sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
4031 					   stack_pointer_rtx,
4032 					   GEN_INT (sp_adjust));
4033 	      /* Emit rtx into instructions list and receive INSN rtx form.  */
4034 	      sp_adjust_insn = emit_insn (sp_adjust_insn);
4035 	    }
4036 	}
4037 
4038       /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
4039          the pattern 'stack_v3pop' is implementad in nds32.md.  */
4040       /* The (const_int 14) means v3pop always pop { $fp $gp $lp }.  */
4041       pop_insn = nds32_gen_stack_v3pop (Rb, Re,
4042 					GEN_INT (14), GEN_INT (0));
4043 
4044       /* Emit pop instruction.  */
4045       emit_insn (pop_insn);
4046     }
4047 }
4048 
4049 /* ------------------------------------------------------------------------ */
4050 
4051 /* Function to test 333-form for load/store instructions.
4052    This is auxiliary extern function for auxiliary macro in nds32.h.
4053    Because it is a little complicated, we use function instead of macro.  */
4054 bool
nds32_ls_333_p(rtx rt,rtx ra,rtx imm,enum machine_mode mode)4055 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
4056 {
4057   if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
4058       && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
4059     {
4060       if (GET_MODE_SIZE (mode) == 4)
4061 	return satisfies_constraint_Iu05 (imm);
4062 
4063       if (GET_MODE_SIZE (mode) == 2)
4064 	return satisfies_constraint_Iu04 (imm);
4065 
4066       if (GET_MODE_SIZE (mode) == 1)
4067 	return satisfies_constraint_Iu03 (imm);
4068     }
4069 
4070   return false;
4071 }
4072 
4073 
4074 /* Functions to expand load_multiple and store_multiple.
4075    They are auxiliary extern functions to help create rtx template.
4076    Check nds32-multiple.md file for the patterns.  */
4077 rtx
nds32_expand_load_multiple(int base_regno,int count,rtx base_addr,rtx basemem)4078 nds32_expand_load_multiple (int base_regno, int count,
4079 			    rtx base_addr, rtx basemem)
4080 {
4081   int par_index;
4082   int offset;
4083   rtx result;
4084   rtx new_addr, mem, reg;
4085 
4086   /* Create the pattern that is presented in nds32-multiple.md.  */
4087 
4088   result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
4089 
4090   for (par_index = 0; par_index < count; par_index++)
4091     {
4092       offset   = par_index * 4;
4093       /* 4-byte for loading data to each register.  */
4094       new_addr = plus_constant (Pmode, base_addr, offset);
4095       mem      = adjust_automodify_address_nv (basemem, SImode,
4096 					       new_addr, offset);
4097       reg      = gen_rtx_REG (SImode, base_regno + par_index);
4098 
4099       XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, reg, mem);
4100     }
4101 
4102   return result;
4103 }
4104 
4105 rtx
nds32_expand_store_multiple(int base_regno,int count,rtx base_addr,rtx basemem)4106 nds32_expand_store_multiple (int base_regno, int count,
4107 			     rtx base_addr, rtx basemem)
4108 {
4109   int par_index;
4110   int offset;
4111   rtx result;
4112   rtx new_addr, mem, reg;
4113 
4114   /* Create the pattern that is presented in nds32-multiple.md.  */
4115 
4116   result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
4117 
4118   for (par_index = 0; par_index < count; par_index++)
4119     {
4120       offset   = par_index * 4;
4121       /* 4-byte for storing data to memory.  */
4122       new_addr = plus_constant (Pmode, base_addr, offset);
4123       mem      = adjust_automodify_address_nv (basemem, SImode,
4124 					       new_addr, offset);
4125       reg      = gen_rtx_REG (SImode, base_regno + par_index);
4126 
4127       XVECEXP (result, 0, par_index) = gen_rtx_SET (VOIDmode, mem, reg);
4128     }
4129 
4130   return result;
4131 }
4132 
4133 /* Function to move block memory content by
4134    using load_multiple and store_multiple.
4135    This is auxiliary extern function to help create rtx template.
4136    Check nds32-multiple.md file for the patterns.  */
4137 int
nds32_expand_movmemqi(rtx dstmem,rtx srcmem,rtx total_bytes,rtx alignment)4138 nds32_expand_movmemqi (rtx dstmem, rtx srcmem, rtx total_bytes, rtx alignment)
4139 {
4140   HOST_WIDE_INT in_words, out_words;
4141   rtx dst_base_reg, src_base_reg;
4142   int maximum_bytes;
4143 
4144   /* Because reduced-set regsiters has few registers
4145      (r0~r5, r6~10, r15, r28~r31, where 'r15' and 'r28~r31'
4146       cannot be used for register allocation),
4147      using 8 registers (32 bytes) for moving memory block
4148      may easily consume all of them.
4149      It makes register allocation/spilling hard to work.
4150      So we only allow maximum=4 registers (16 bytes) for
4151      moving memory block under reduced-set registers.  */
4152   if (TARGET_REDUCED_REGS)
4153     maximum_bytes = 16;
4154   else
4155     maximum_bytes = 32;
4156 
4157   /* 1. Total_bytes is integer for sure.
4158      2. Alignment is integer for sure.
4159      3. Maximum 4 or 8 registers, 4 * 4 = 16 bytes, 8 * 4 = 32 bytes.
4160      4. Requires (n * 4) block size.
4161      5. Requires 4-byte alignment.  */
4162   if (GET_CODE (total_bytes) != CONST_INT
4163       || GET_CODE (alignment) != CONST_INT
4164       || INTVAL (total_bytes) > maximum_bytes
4165       || INTVAL (total_bytes) & 3
4166       || INTVAL (alignment) & 3)
4167     return 0;
4168 
4169   dst_base_reg = copy_to_mode_reg (SImode, XEXP (dstmem, 0));
4170   src_base_reg = copy_to_mode_reg (SImode, XEXP (srcmem, 0));
4171 
4172   out_words = in_words = INTVAL (total_bytes) / UNITS_PER_WORD;
4173 
4174   emit_insn (nds32_expand_load_multiple (0, in_words, src_base_reg, srcmem));
4175   emit_insn (nds32_expand_store_multiple (0, out_words, dst_base_reg, dstmem));
4176 
4177   /* Successfully create patterns, return 1.  */
4178   return 1;
4179 }
4180 
4181 /* Function to check whether the OP is a valid load/store operation.
4182    This is a helper function for the predicates:
4183    'nds32_load_multiple_operation' and 'nds32_store_multiple_operation'
4184    in predicates.md file.
4185 
4186    The OP is supposed to be a parallel rtx.
4187    For each element within this parallel rtx:
4188      (set (reg) (mem addr)) is the form for load operation.
4189      (set (mem addr) (reg)) is the form for store operation.
4190    We have to extract reg and mem of every element and
4191    check if the information is valid for multiple load/store operation.  */
4192 bool
nds32_valid_multiple_load_store(rtx op,bool load_p)4193 nds32_valid_multiple_load_store (rtx op, bool load_p)
4194 {
4195   int count;
4196   int first_elt_regno;
4197   rtx elt;
4198 
4199   /* Get the counts of elements in the parallel rtx.  */
4200   count = XVECLEN (op, 0);
4201   /* Pick up the first element.  */
4202   elt = XVECEXP (op, 0, 0);
4203 
4204   /* Perform some quick check for the first element in the parallel rtx.  */
4205   if (GET_CODE (elt) != SET
4206       || count <= 1
4207       || count > 8)
4208     return false;
4209 
4210   /* Pick up regno of first element for further detail checking.
4211      Note that the form is different between load and store operation.  */
4212   if (load_p)
4213     {
4214       if (GET_CODE (SET_DEST (elt)) != REG
4215 	  || GET_CODE (SET_SRC (elt)) != MEM)
4216 	return false;
4217 
4218       first_elt_regno = REGNO (SET_DEST (elt));
4219     }
4220   else
4221     {
4222       if (GET_CODE (SET_SRC (elt)) != REG
4223 	  || GET_CODE (SET_DEST (elt)) != MEM)
4224 	return false;
4225 
4226       first_elt_regno = REGNO (SET_SRC (elt));
4227     }
4228 
4229   /* Perform detail check for each element.
4230      Refer to nds32-multiple.md for more information
4231      about following checking.
4232      The starting element of parallel rtx is index 0.  */
4233   if (!nds32_consecutive_registers_load_store_p (op, load_p, 0,
4234 						 first_elt_regno,
4235 						 count))
4236     return false;
4237 
4238   /* Pass all test, this is a valid rtx.  */
4239   return true;
4240 }
4241 
4242 /* Function to check whether the OP is a valid stack push/pop operation.
4243    For a valid stack operation, it must satisfy following conditions:
4244      1. Consecutive registers push/pop operations.
4245      2. Valid $fp/$gp/$lp push/pop operations.
4246      3. The last element must be stack adjustment rtx.
4247    See the prologue/epilogue implementation for details.  */
4248 bool
nds32_valid_stack_push_pop(rtx op,bool push_p)4249 nds32_valid_stack_push_pop (rtx op, bool push_p)
4250 {
4251   int index;
4252   int total_count;
4253   int rest_count;
4254   int first_regno;
4255   rtx elt;
4256   rtx elt_reg;
4257   rtx elt_mem;
4258   rtx elt_plus;
4259 
4260   /* Get the counts of elements in the parallel rtx.  */
4261   total_count = XVECLEN (op, 0);
4262 
4263   /* Perform some quick check for that every element should be 'set'.  */
4264   for (index = 0; index < total_count; index++)
4265     {
4266       elt = XVECEXP (op, 0, index);
4267       if (GET_CODE (elt) != SET)
4268         return false;
4269     }
4270 
4271   /* For push operation, the parallel rtx looks like:
4272      (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
4273                      (reg:SI Rb))
4274                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
4275                      (reg:SI Rb+1))
4276                 ...
4277                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
4278                      (reg:SI Re))
4279                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
4280                      (reg:SI FP_REGNUM))
4281                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
4282                      (reg:SI GP_REGNUM))
4283                 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
4284                      (reg:SI LP_REGNUM))
4285                 (set (reg:SI SP_REGNUM)
4286                      (plus (reg:SI SP_REGNUM) (const_int -32)))])
4287 
4288      For pop operation, the parallel rtx looks like:
4289      (parallel [(set (reg:SI Rb)
4290                      (mem (reg:SI SP_REGNUM)))
4291                 (set (reg:SI Rb+1)
4292                      (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
4293                 ...
4294                 (set (reg:SI Re)
4295                      (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
4296                 (set (reg:SI FP_REGNUM)
4297                      (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
4298                 (set (reg:SI GP_REGNUM)
4299                      (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
4300                 (set (reg:SI LP_REGNUM)
4301                      (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
4302                 (set (reg:SI SP_REGNUM)
4303                      (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
4304 
4305   /* 1. Consecutive registers push/pop operations.
4306         We need to calculate how many registers should be consecutive.
4307         The $sp adjustment rtx, $fp push rtx, $gp push rtx,
4308         and $lp push rtx are excluded.  */
4309 
4310   /* Exclude last $sp adjustment rtx.  */
4311   rest_count = total_count - 1;
4312   /* Exclude $fp, $gp, and $lp if they are in the parallel rtx.  */
4313   if (cfun->machine->fp_size)
4314     rest_count--;
4315   if (cfun->machine->gp_size)
4316     rest_count--;
4317   if (cfun->machine->lp_size)
4318     rest_count--;
4319 
4320   if (rest_count > 0)
4321     {
4322       elt = XVECEXP (op, 0, 0);
4323       /* Pick up register element.  */
4324       elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
4325       first_regno = REGNO (elt_reg);
4326 
4327       /* The 'push' operation is a kind of store operation.
4328          The 'pop' operation is a kind of load operation.
4329          Pass corresponding false/true as second argument (bool load_p).
4330          The par_index is supposed to start with index 0.  */
4331       if (!nds32_consecutive_registers_load_store_p (op,
4332 						     !push_p ? true : false,
4333 						     0,
4334 						     first_regno,
4335 						     rest_count))
4336         return false;
4337     }
4338 
4339   /* 2. Valid $fp/$gp/$lp push/pop operations.
4340         Remember to set start index for checking them.  */
4341 
4342   /* The rest_count is the start index for checking $fp/$gp/$lp.  */
4343   index = rest_count;
4344   /* If index < 0, this parallel rtx is definitely
4345      not a valid stack push/pop operation.  */
4346   if (index < 0)
4347     return false;
4348 
4349   /* Check $fp/$gp/$lp one by one.
4350      We use 'push_p' to pick up reg rtx and mem rtx.  */
4351   if (cfun->machine->fp_size)
4352     {
4353       elt = XVECEXP (op, 0, index);
4354       elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
4355       elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
4356       index++;
4357 
4358       if (GET_CODE (elt_mem) != MEM
4359           || GET_CODE (elt_reg) != REG
4360           || REGNO (elt_reg) != FP_REGNUM)
4361         return false;
4362     }
4363   if (cfun->machine->gp_size)
4364     {
4365       elt = XVECEXP (op, 0, index);
4366       elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
4367       elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
4368       index++;
4369 
4370       if (GET_CODE (elt_mem) != MEM
4371           || GET_CODE (elt_reg) != REG
4372           || REGNO (elt_reg) != GP_REGNUM)
4373         return false;
4374     }
4375   if (cfun->machine->lp_size)
4376     {
4377       elt = XVECEXP (op, 0, index);
4378       elt_mem = push_p ? SET_DEST (elt) : SET_SRC (elt);
4379       elt_reg = push_p ? SET_SRC (elt) : SET_DEST (elt);
4380       index++;
4381 
4382       if (GET_CODE (elt_mem) != MEM
4383           || GET_CODE (elt_reg) != REG
4384           || REGNO (elt_reg) != LP_REGNUM)
4385         return false;
4386     }
4387 
4388   /* 3. The last element must be stack adjustment rtx.
4389         Its form of rtx should be:
4390           (set (reg:SI SP_REGNUM)
4391                (plus (reg:SI SP_REGNUM) (const_int X)))
4392         The X could be positive or negative value.  */
4393 
4394   /* Pick up the last element.  */
4395   elt = XVECEXP (op, 0, total_count - 1);
4396 
4397   /* Extract its destination and source rtx.  */
4398   elt_reg  = SET_DEST (elt);
4399   elt_plus = SET_SRC (elt);
4400 
4401   /* Check this is (set (stack_reg) (plus stack_reg const)) pattern.  */
4402   if (GET_CODE (elt_reg) != REG
4403       || GET_CODE (elt_plus) != PLUS
4404       || REGNO (elt_reg) != SP_REGNUM)
4405     return false;
4406 
4407   /* Pass all test, this is a valid rtx.  */
4408   return true;
4409 }
4410 
4411 /* Computing the Length of an Insn.
4412    Modifies the length assigned to instruction INSN.
4413    LEN is the initially computed length of the insn.  */
4414 int
nds32_adjust_insn_length(rtx insn,int length)4415 nds32_adjust_insn_length (rtx insn, int length)
4416 {
4417   rtx src, dst;
4418 
4419   switch (recog_memoized (insn))
4420     {
4421     case CODE_FOR_move_df:
4422     case CODE_FOR_move_di:
4423       /* Adjust length of movd44 to 2.  */
4424       src = XEXP (PATTERN (insn), 1);
4425       dst = XEXP (PATTERN (insn), 0);
4426 
4427       if (REG_P (src)
4428 	  && REG_P (dst)
4429 	  && (REGNO (src) % 2) == 0
4430 	  && (REGNO (dst) % 2) == 0)
4431 	length = 2;
4432       break;
4433 
4434     default:
4435       break;
4436     }
4437 
4438   return length;
4439 }
4440 
4441 
4442 /* Function to check if 'bclr' instruction can be used with IVAL.  */
4443 int
nds32_can_use_bclr_p(int ival)4444 nds32_can_use_bclr_p (int ival)
4445 {
4446   int one_bit_count;
4447 
4448   /* Calculate the number of 1-bit of (~ival), if there is only one 1-bit,
4449      it means the original ival has only one 0-bit,
4450      So it is ok to perform 'bclr' operation.  */
4451 
4452   one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (~ival));
4453 
4454   /* 'bclr' is a performance extension instruction.  */
4455   return (TARGET_PERF_EXT && (one_bit_count == 1));
4456 }
4457 
4458 /* Function to check if 'bset' instruction can be used with IVAL.  */
4459 int
nds32_can_use_bset_p(int ival)4460 nds32_can_use_bset_p (int ival)
4461 {
4462   int one_bit_count;
4463 
4464   /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
4465      it is ok to perform 'bset' operation.  */
4466 
4467   one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival));
4468 
4469   /* 'bset' is a performance extension instruction.  */
4470   return (TARGET_PERF_EXT && (one_bit_count == 1));
4471 }
4472 
4473 /* Function to check if 'btgl' instruction can be used with IVAL.  */
4474 int
nds32_can_use_btgl_p(int ival)4475 nds32_can_use_btgl_p (int ival)
4476 {
4477   int one_bit_count;
4478 
4479   /* Caculate the number of 1-bit of ival, if there is only one 1-bit,
4480      it is ok to perform 'btgl' operation.  */
4481 
4482   one_bit_count = popcount_hwi ((unsigned HOST_WIDE_INT) (ival));
4483 
4484   /* 'btgl' is a performance extension instruction.  */
4485   return (TARGET_PERF_EXT && (one_bit_count == 1));
4486 }
4487 
4488 /* Function to check if 'bitci' instruction can be used with IVAL.  */
4489 int
nds32_can_use_bitci_p(int ival)4490 nds32_can_use_bitci_p (int ival)
4491 {
4492   /* If we are using V3 ISA, we have 'bitci' instruction.
4493      Try to see if we can present 'andi' semantic with
4494      such 'bit-clear-immediate' operation.
4495      For example, 'andi $r0,$r0,0xfffffffc' can be
4496      presented with 'bitci $r0,$r0,3'.  */
4497   return (TARGET_ISA_V3
4498 	  && (ival < 0)
4499 	  && satisfies_constraint_Iu15 (gen_int_mode (~ival, SImode)));
4500 }
4501 
4502 
4503 /* Return true if is load/store with SYMBOL_REF addressing mode
4504    and memory mode is SImode.  */
4505 bool
nds32_symbol_load_store_p(rtx insn)4506 nds32_symbol_load_store_p (rtx insn)
4507 {
4508   rtx mem_src = NULL_RTX;
4509 
4510   switch (get_attr_type (insn))
4511     {
4512     case TYPE_LOAD:
4513       mem_src = SET_SRC (PATTERN (insn));
4514       break;
4515     case TYPE_STORE:
4516       mem_src = SET_DEST (PATTERN (insn));
4517       break;
4518     default:
4519       break;
4520     }
4521 
4522   /* Find load/store insn with addressing mode is SYMBOL_REF.  */
4523   if (mem_src != NULL_RTX)
4524     {
4525       if ((GET_CODE (mem_src) == ZERO_EXTEND)
4526 	  || (GET_CODE (mem_src) == SIGN_EXTEND))
4527 	mem_src = XEXP (mem_src, 0);
4528 
4529       if ((GET_CODE (XEXP (mem_src, 0)) == SYMBOL_REF)
4530 	   || (GET_CODE (XEXP (mem_src, 0)) == LO_SUM))
4531 	return true;
4532     }
4533 
4534   return false;
4535 }
4536 
4537 /* Function to determine whether it is worth to do fp_as_gp optimization.
4538    Return 0: It is NOT worth to do fp_as_gp optimization.
4539    Return 1: It is APPROXIMATELY worth to do fp_as_gp optimization.
4540    Note that if it is worth to do fp_as_gp optimization,
4541    we MUST set FP_REGNUM ever live in this function.  */
4542 int
nds32_fp_as_gp_check_available(void)4543 nds32_fp_as_gp_check_available (void)
4544 {
4545   /* If there exists ANY of following conditions,
4546      we DO NOT perform fp_as_gp optimization:
4547        1. TARGET_FORBID_FP_AS_GP is set
4548           regardless of the TARGET_FORCE_FP_AS_GP.
4549        2. User explicitly uses 'naked' attribute.
4550        3. Not optimize for size.
4551        4. Need frame pointer.
4552        5. If $fp is already required to be saved,
4553           it means $fp is already choosen by register allocator.
4554           Thus we better not to use it for fp_as_gp optimization.
4555        6. This function is a vararg function.
4556           DO NOT apply fp_as_gp optimization on this function
4557           because it may change and break stack frame.
4558        7. The epilogue is empty.
4559           This happens when the function uses exit()
4560           or its attribute is no_return.
4561           In that case, compiler will not expand epilogue
4562           so that we have no chance to output .omit_fp_end directive.  */
4563   if (TARGET_FORBID_FP_AS_GP
4564       || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
4565       || !optimize_size
4566       || frame_pointer_needed
4567       || NDS32_REQUIRED_CALLEE_SAVED_P (FP_REGNUM)
4568       || (cfun->stdarg == 1)
4569       || (find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == NULL))
4570     return 0;
4571 
4572   /* Now we can check the possibility of using fp_as_gp optimization.  */
4573   if (TARGET_FORCE_FP_AS_GP)
4574     {
4575       /* User explicitly issues -mforce-fp-as-gp option.  */
4576       df_set_regs_ever_live (FP_REGNUM, 1);
4577       return 1;
4578     }
4579   else
4580     {
4581       /* In the following we are going to evaluate whether
4582          it is worth to do fp_as_gp optimization.  */
4583       int good_gain     = 0;
4584       int symbol_count  = 0;
4585 
4586       int threshold;
4587       rtx insn;
4588 
4589       /* We check if there already requires prologue.
4590          Note that $gp will be saved in prologue for PIC code generation.
4591          After that, we can set threshold by the existence of prologue.
4592          Each fp-implied instruction will gain 2-byte code size
4593          from gp-aware instruction, so we have following heuristics.  */
4594       if (flag_pic
4595 	  || nds32_have_prologue_p ())
4596 	{
4597 	  /* Have-prologue:
4598 	       Compiler already intends to generate prologue content,
4599 	       so the fp_as_gp optimization will only insert
4600 	       'la $fp,_FP_BASE_' instruction, which will be
4601 	       converted into 4-byte instruction at link time.
4602 	       The threshold is "3" symbol accesses, 2 + 2 + 2 > 4.  */
4603 	  threshold = 3;
4604 	}
4605       else
4606 	{
4607 	  /* None-prologue:
4608 	       Compiler originally does not generate prologue content,
4609 	       so the fp_as_gp optimization will NOT ONLY insert
4610 	       'la $fp,_FP_BASE' instruction, but also causes
4611 	       push/pop instructions.
4612 	       If we are using v3push (push25/pop25),
4613 	       the threshold is "5" symbol accesses, 5*2 > 4 + 2 + 2;
4614 	       If we are using normal push (smw/lmw),
4615 	       the threshold is "5+2" symbol accesses 7*2 > 4 + 4 + 4.  */
4616 	  threshold = 5 + (TARGET_V3PUSH ? 0 : 2);
4617 	}
4618 
4619       /* We would like to traverse every instruction in this function.
4620          So we need to have push_topmost_sequence()/pop_topmost_sequence()
4621          surrounding our for-loop evaluation.  */
4622       push_topmost_sequence ();
4623       /* Counting the insn number which the addressing mode is symbol.  */
4624       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4625 	{
4626 	  if (single_set (insn) && nds32_symbol_load_store_p (insn))
4627 	    symbol_count++;
4628 
4629 	  if (symbol_count == threshold)
4630 	    {
4631 	      good_gain = 1;
4632 	      break;
4633 	    }
4634 	}
4635       pop_topmost_sequence ();
4636 
4637       /* Enable fp_as_gp optimization when potential gain is good enough.  */
4638       if (good_gain)
4639 	{
4640 	  df_set_regs_ever_live (FP_REGNUM, 1);
4641 	  return 1;
4642 	}
4643     }
4644 
4645   /* By default we return 0.  */
4646   return 0;
4647 }
4648 
4649 
4650 /* Function to generate PC relative jump table.
4651    Refer to nds32.md for more details.
4652 
4653    The following is the sample for the case that diff value
4654    can be presented in '.short' size.
4655 
4656      addi    $r1, $r1, -(case_lower_bound)
4657      slti    $ta, $r1, (case_number)
4658      beqz    $ta, .L_skip_label
4659 
4660      la      $ta, .L35             ! get jump table address
4661      lh      $r1, [$ta + $r1 << 1] ! load symbol diff from jump table entry
4662      addi    $ta, $r1, $ta
4663      jr5     $ta
4664 
4665      ! jump table entry
4666    L35:
4667      .short  .L25-.L35
4668      .short  .L26-.L35
4669      .short  .L27-.L35
4670      .short  .L28-.L35
4671      .short  .L29-.L35
4672      .short  .L30-.L35
4673      .short  .L31-.L35
4674      .short  .L32-.L35
4675      .short  .L33-.L35
4676      .short  .L34-.L35 */
4677 const char *
nds32_output_casesi_pc_relative(rtx * operands)4678 nds32_output_casesi_pc_relative (rtx *operands)
4679 {
4680   enum machine_mode mode;
4681   rtx diff_vec;
4682 
4683   diff_vec = PATTERN (NEXT_INSN (operands[1]));
4684 
4685   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
4686 
4687   /* Step C: "t <-- operands[1]".  */
4688   output_asm_insn ("la\t$ta, %l1", operands);
4689 
4690   /* Get the mode of each element in the difference vector.  */
4691   mode = GET_MODE (diff_vec);
4692 
4693   /* Step D: "z <-- (mem (plus (operands[0] << m) t))",
4694      where m is 0, 1, or 2 to load address-diff value from table.  */
4695   switch (mode)
4696     {
4697     case QImode:
4698       output_asm_insn ("lb\t%2, [$ta + %0 << 0]", operands);
4699       break;
4700     case HImode:
4701       output_asm_insn ("lh\t%2, [$ta + %0 << 1]", operands);
4702       break;
4703     case SImode:
4704       output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
4705       break;
4706     default:
4707       gcc_unreachable ();
4708     }
4709 
4710   /* Step E: "t <-- z + t".
4711      Add table label_ref with address-diff value to
4712      obtain target case address.  */
4713   output_asm_insn ("add\t$ta, %2, $ta", operands);
4714 
4715   /* Step F: jump to target with register t.  */
4716   if (TARGET_16_BIT)
4717     return "jr5\t$ta";
4718   else
4719     return "jr\t$ta";
4720 }
4721 
4722 /* Function to generate normal jump table.  */
4723 const char *
nds32_output_casesi(rtx * operands)4724 nds32_output_casesi (rtx *operands)
4725 {
4726   /* Step C: "t <-- operands[1]".  */
4727   output_asm_insn ("la\t$ta, %l1", operands);
4728 
4729   /* Step D: "z <-- (mem (plus (operands[0] << 2) t))".  */
4730   output_asm_insn ("lw\t%2, [$ta + %0 << 2]", operands);
4731 
4732   /* No need to perform Step E, which is only used for
4733      pc relative jump table.  */
4734 
4735   /* Step F: jump to target with register z.  */
4736   if (TARGET_16_BIT)
4737     return "jr5\t%2";
4738   else
4739     return "jr\t%2";
4740 }
4741 
4742 
4743 /* Function to return memory format.  */
4744 enum nds32_16bit_address_type
nds32_mem_format(rtx op)4745 nds32_mem_format (rtx op)
4746 {
4747   enum machine_mode mode_test;
4748   int val;
4749   int regno;
4750 
4751   if (!TARGET_16_BIT)
4752     return ADDRESS_NOT_16BIT_FORMAT;
4753 
4754   mode_test = GET_MODE (op);
4755 
4756   op = XEXP (op, 0);
4757 
4758   /* 45 format.  */
4759   if (GET_CODE (op) == REG && (mode_test == SImode))
4760     return ADDRESS_REG;
4761 
4762   /* 333 format for QI/HImode.  */
4763   if (GET_CODE (op) == REG && (REGNO (op) < R8_REGNUM))
4764     return ADDRESS_LO_REG_IMM3U;
4765 
4766   /* post_inc 333 format.  */
4767   if ((GET_CODE (op) == POST_INC) && (mode_test == SImode))
4768     {
4769       regno = REGNO(XEXP (op, 0));
4770 
4771       if (regno < 8)
4772 	return ADDRESS_POST_INC_LO_REG_IMM3U;
4773     }
4774 
4775   /* post_inc 333 format.  */
4776   if ((GET_CODE (op) == POST_MODIFY)
4777       && (mode_test == SImode)
4778       && (REG_P (XEXP (XEXP (op, 1), 0)))
4779       && (CONST_INT_P (XEXP (XEXP (op, 1), 1))))
4780     {
4781       regno = REGNO (XEXP (XEXP (op, 1), 0));
4782       val = INTVAL (XEXP (XEXP (op, 1), 1));
4783       if (regno < 8 && val < 32)
4784 	return ADDRESS_POST_INC_LO_REG_IMM3U;
4785     }
4786 
4787   if ((GET_CODE (op) == PLUS)
4788       && (GET_CODE (XEXP (op, 0)) == REG)
4789       && (GET_CODE (XEXP (op, 1)) == CONST_INT))
4790     {
4791       val = INTVAL (XEXP (op, 1));
4792 
4793       regno = REGNO(XEXP (op, 0));
4794 
4795       if (regno > 7
4796 	  && regno != SP_REGNUM
4797 	  && regno != FP_REGNUM)
4798 	return ADDRESS_NOT_16BIT_FORMAT;
4799 
4800       switch (mode_test)
4801 	{
4802 	case QImode:
4803 	  /* 333 format.  */
4804 	  if (val >= 0 && val < 8 && regno < 8)
4805 	    return ADDRESS_LO_REG_IMM3U;
4806 	  break;
4807 
4808 	case HImode:
4809 	  /* 333 format.  */
4810 	  if (val >= 0 && val < 16 && (val % 2 == 0) && regno < 8)
4811 	    return ADDRESS_LO_REG_IMM3U;
4812 	  break;
4813 
4814 	case SImode:
4815 	case SFmode:
4816 	case DFmode:
4817 	  /* fp imply 37 format.  */
4818 	  if ((regno == FP_REGNUM) &&
4819 	      (val >= 0 && val < 512 && (val % 4 == 0)))
4820 	    return ADDRESS_FP_IMM7U;
4821 	  /* sp imply 37 format.  */
4822 	  else if ((regno == SP_REGNUM) &&
4823 		   (val >= 0 && val < 512 && (val % 4 == 0)))
4824 	    return ADDRESS_SP_IMM7U;
4825 	  /* 333 format.  */
4826 	  else if (val >= 0 && val < 32 && (val % 4 == 0) && regno < 8)
4827 	    return ADDRESS_LO_REG_IMM3U;
4828 	  break;
4829 
4830 	default:
4831 	  break;
4832 	}
4833     }
4834 
4835   return ADDRESS_NOT_16BIT_FORMAT;
4836 }
4837 
4838 /* Output 16-bit store.  */
4839 const char *
nds32_output_16bit_store(rtx * operands,int byte)4840 nds32_output_16bit_store (rtx *operands, int byte)
4841 {
4842   char pattern[100];
4843   char size;
4844   rtx code = XEXP (operands[0], 0);
4845 
4846   size = nds32_byte_to_size (byte);
4847 
4848   switch (nds32_mem_format (operands[0]))
4849     {
4850     case ADDRESS_REG:
4851       operands[0] = code;
4852       output_asm_insn ("swi450\t%1, [%0]", operands);
4853       break;
4854     case ADDRESS_LO_REG_IMM3U:
4855       snprintf (pattern, sizeof (pattern), "s%ci333\t%%1, %%0", size);
4856       output_asm_insn (pattern, operands);
4857       break;
4858     case ADDRESS_POST_INC_LO_REG_IMM3U:
4859       snprintf (pattern, sizeof (pattern), "s%ci333.bi\t%%1, %%0", size);
4860       output_asm_insn (pattern, operands);
4861       break;
4862     case ADDRESS_FP_IMM7U:
4863       output_asm_insn ("swi37\t%1, %0", operands);
4864       break;
4865     case ADDRESS_SP_IMM7U:
4866       /* Get immediate value and set back to operands[1].  */
4867       operands[0] = XEXP (code, 1);
4868       output_asm_insn ("swi37.sp\t%1, [ + (%0)]", operands);
4869       break;
4870     default:
4871       break;
4872     }
4873 
4874   return "";
4875 }
4876 
4877 /* Output 16-bit load.  */
4878 const char *
nds32_output_16bit_load(rtx * operands,int byte)4879 nds32_output_16bit_load (rtx *operands, int byte)
4880 {
4881   char pattern[100];
4882   unsigned char size;
4883   rtx code = XEXP (operands[1], 0);
4884 
4885   size = nds32_byte_to_size (byte);
4886 
4887   switch (nds32_mem_format (operands[1]))
4888     {
4889     case ADDRESS_REG:
4890       operands[1] = code;
4891       output_asm_insn ("lwi450\t%0, [%1]", operands);
4892       break;
4893     case ADDRESS_LO_REG_IMM3U:
4894       snprintf (pattern, sizeof (pattern), "l%ci333\t%%0, %%1", size);
4895       output_asm_insn (pattern, operands);
4896       break;
4897     case ADDRESS_POST_INC_LO_REG_IMM3U:
4898       snprintf (pattern, sizeof (pattern), "l%ci333.bi\t%%0, %%1", size);
4899       output_asm_insn (pattern, operands);
4900       break;
4901     case ADDRESS_FP_IMM7U:
4902       output_asm_insn ("lwi37\t%0, %1", operands);
4903       break;
4904     case ADDRESS_SP_IMM7U:
4905       /* Get immediate value and set back to operands[0].  */
4906       operands[1] = XEXP (code, 1);
4907       output_asm_insn ("lwi37.sp\t%0, [ + (%1)]", operands);
4908       break;
4909     default:
4910       break;
4911     }
4912 
4913   return "";
4914 }
4915 
4916 /* Output 32-bit store.  */
4917 const char *
nds32_output_32bit_store(rtx * operands,int byte)4918 nds32_output_32bit_store (rtx *operands, int byte)
4919 {
4920   char pattern[100];
4921   unsigned char size;
4922   rtx code = XEXP (operands[0], 0);
4923 
4924   size = nds32_byte_to_size (byte);
4925 
4926   switch (GET_CODE (code))
4927     {
4928     case REG:
4929       /* (mem (reg X))
4930 	 => access location by using register,
4931 	 use "sbi / shi / swi" */
4932       snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size);
4933       break;
4934 
4935     case SYMBOL_REF:
4936     case CONST:
4937       /* (mem (symbol_ref X))
4938 	 (mem (const (...)))
4939 	 => access global variables,
4940 	 use "sbi.gp / shi.gp / swi.gp" */
4941       operands[0] = XEXP (operands[0], 0);
4942       snprintf (pattern, sizeof (pattern), "s%ci.gp\t%%1, [ + %%0]", size);
4943       break;
4944 
4945     case POST_INC:
4946       /* (mem (post_inc reg))
4947 	 => access location by using register which will be post increment,
4948 	 use "sbi.bi / shi.bi / swi.bi" */
4949       snprintf (pattern, sizeof (pattern),
4950 		"s%ci.bi\t%%1, %%0, %d", size, byte);
4951       break;
4952 
4953     case POST_DEC:
4954       /* (mem (post_dec reg))
4955 	 => access location by using register which will be post decrement,
4956 	 use "sbi.bi / shi.bi / swi.bi" */
4957       snprintf (pattern, sizeof (pattern),
4958 		"s%ci.bi\t%%1, %%0, -%d", size, byte);
4959       break;
4960 
4961     case POST_MODIFY:
4962       switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
4963 	{
4964 	case REG:
4965 	case SUBREG:
4966 	  /* (mem (post_modify (reg) (plus (reg) (reg))))
4967 	     => access location by using register which will be
4968 	     post modified with reg,
4969 	     use "sb.bi/ sh.bi / sw.bi" */
4970 	  snprintf (pattern, sizeof (pattern), "s%c.bi\t%%1, %%0", size);
4971 	  break;
4972 	case CONST_INT:
4973 	  /* (mem (post_modify (reg) (plus (reg) (const_int))))
4974 	     => access location by using register which will be
4975 	     post modified with const_int,
4976 	     use "sbi.bi/ shi.bi / swi.bi" */
4977 	  snprintf (pattern, sizeof (pattern), "s%ci.bi\t%%1, %%0", size);
4978 	  break;
4979 	default:
4980 	  abort ();
4981 	}
4982       break;
4983 
4984     case PLUS:
4985       switch (GET_CODE (XEXP (code, 1)))
4986 	{
4987 	case REG:
4988 	case SUBREG:
4989 	  /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
4990 	     => access location by adding two registers,
4991 	     use "sb / sh / sw" */
4992 	  snprintf (pattern, sizeof (pattern), "s%c\t%%1, %%0", size);
4993 	  break;
4994 	case CONST_INT:
4995 	  /* (mem (plus reg const_int))
4996 	     => access location by adding one register with const_int,
4997 	     use "sbi / shi / swi" */
4998 	  snprintf (pattern, sizeof (pattern), "s%ci\t%%1, %%0", size);
4999 	  break;
5000 	default:
5001 	  abort ();
5002 	}
5003       break;
5004 
5005     case LO_SUM:
5006       operands[2] = XEXP (code, 1);
5007       operands[0] = XEXP (code, 0);
5008       snprintf (pattern, sizeof (pattern),
5009 		"s%ci\t%%1, [%%0 + lo12(%%2)]", size);
5010       break;
5011 
5012     default:
5013       abort ();
5014     }
5015 
5016   output_asm_insn (pattern, operands);
5017   return "";
5018 }
5019 
5020 /* Output 32-bit load.  */
5021 const char *
nds32_output_32bit_load(rtx * operands,int byte)5022 nds32_output_32bit_load (rtx *operands, int byte)
5023 {
5024   char pattern[100];
5025   unsigned char size;
5026   rtx code;
5027 
5028   code = XEXP (operands[1], 0);
5029 
5030   size = nds32_byte_to_size (byte);
5031 
5032   switch (GET_CODE (code))
5033     {
5034     case REG:
5035       /* (mem (reg X))
5036 	 => access location by using register,
5037 	 use "lbi / lhi / lwi" */
5038       snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size);
5039       break;
5040 
5041     case SYMBOL_REF:
5042     case CONST:
5043       /* (mem (symbol_ref X))
5044 	 (mem (const (...)))
5045 	 => access global variables,
5046 	 use "lbi.gp / lhi.gp / lwi.gp" */
5047       operands[1] = XEXP (operands[1], 0);
5048       snprintf (pattern, sizeof (pattern), "l%ci.gp\t%%0, [ + %%1]", size);
5049       break;
5050 
5051     case POST_INC:
5052       /* (mem (post_inc reg))
5053 	 => access location by using register which will be post increment,
5054 	 use "lbi.bi / lhi.bi / lwi.bi" */
5055       snprintf (pattern, sizeof (pattern),
5056 		"l%ci.bi\t%%0, %%1, %d", size, byte);
5057       break;
5058 
5059     case POST_DEC:
5060       /* (mem (post_dec reg))
5061 	 => access location by using register which will be post decrement,
5062 	 use "lbi.bi / lhi.bi / lwi.bi" */
5063       snprintf (pattern, sizeof (pattern),
5064 		"l%ci.bi\t%%0, %%1, -%d", size, byte);
5065       break;
5066 
5067     case POST_MODIFY:
5068       switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
5069 	{
5070 	case REG:
5071 	case SUBREG:
5072 	  /* (mem (post_modify (reg) (plus (reg) (reg))))
5073 	     => access location by using register which will be
5074 	     post modified with reg,
5075 	     use "lb.bi/ lh.bi / lw.bi" */
5076 	  snprintf (pattern, sizeof (pattern), "l%c.bi\t%%0, %%1", size);
5077 	  break;
5078 	case CONST_INT:
5079 	  /* (mem (post_modify (reg) (plus (reg) (const_int))))
5080 	     => access location by using register which will be
5081 	     post modified with const_int,
5082 	     use "lbi.bi/ lhi.bi / lwi.bi" */
5083 	  snprintf (pattern, sizeof (pattern), "l%ci.bi\t%%0, %%1", size);
5084 	  break;
5085 	default:
5086 	  abort ();
5087 	}
5088       break;
5089 
5090     case PLUS:
5091       switch (GET_CODE (XEXP (code, 1)))
5092 	{
5093 	case REG:
5094 	case SUBREG:
5095 	  /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
5096 	     use "lb / lh / lw" */
5097 	  snprintf (pattern, sizeof (pattern), "l%c\t%%0, %%1", size);
5098 	  break;
5099 	case CONST_INT:
5100 	  /* (mem (plus reg const_int))
5101 	     => access location by adding one register with const_int,
5102 	     use "lbi / lhi / lwi" */
5103 	  snprintf (pattern, sizeof (pattern), "l%ci\t%%0, %%1", size);
5104 	  break;
5105 	default:
5106 	  abort ();
5107 	}
5108       break;
5109 
5110     case LO_SUM:
5111       operands[2] = XEXP (code, 1);
5112       operands[1] = XEXP (code, 0);
5113       snprintf (pattern, sizeof (pattern),
5114 		"l%ci\t%%0, [%%1 + lo12(%%2)]", size);
5115       break;
5116 
5117     default:
5118       abort ();
5119     }
5120 
5121   output_asm_insn (pattern, operands);
5122   return "";
5123 }
5124 
5125 /* Output 32-bit load with signed extension.  */
5126 const char *
nds32_output_32bit_load_s(rtx * operands,int byte)5127 nds32_output_32bit_load_s (rtx *operands, int byte)
5128 {
5129   char pattern[100];
5130   unsigned char size;
5131   rtx code;
5132 
5133   code = XEXP (operands[1], 0);
5134 
5135   size = nds32_byte_to_size (byte);
5136 
5137   switch (GET_CODE (code))
5138     {
5139     case REG:
5140       /* (mem (reg X))
5141          => access location by using register,
5142          use "lbsi / lhsi" */
5143       snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size);
5144       break;
5145 
5146     case SYMBOL_REF:
5147     case CONST:
5148       /* (mem (symbol_ref X))
5149          (mem (const (...)))
5150          => access global variables,
5151          use "lbsi.gp / lhsi.gp" */
5152       operands[1] = XEXP (operands[1], 0);
5153       snprintf (pattern, sizeof (pattern), "l%csi.gp\t%%0, [ + %%1]", size);
5154       break;
5155 
5156     case POST_INC:
5157       /* (mem (post_inc reg))
5158          => access location by using register which will be post increment,
5159          use "lbsi.bi / lhsi.bi" */
5160       snprintf (pattern, sizeof (pattern),
5161 		"l%csi.bi\t%%0, %%1, %d", size, byte);
5162       break;
5163 
5164     case POST_DEC:
5165       /* (mem (post_dec reg))
5166          => access location by using register which will be post decrement,
5167          use "lbsi.bi / lhsi.bi" */
5168       snprintf (pattern, sizeof (pattern),
5169 		"l%csi.bi\t%%0, %%1, -%d", size, byte);
5170       break;
5171 
5172     case POST_MODIFY:
5173       switch (GET_CODE (XEXP (XEXP (code, 1), 1)))
5174 	{
5175 	case REG:
5176 	case SUBREG:
5177 	  /* (mem (post_modify (reg) (plus (reg) (reg))))
5178 	     => access location by using register which will be
5179 	     post modified with reg,
5180 	     use "lbs.bi/ lhs.bi" */
5181 	  snprintf (pattern, sizeof (pattern), "l%cs.bi\t%%0, %%1", size);
5182 	  break;
5183 	case CONST_INT:
5184 	  /* (mem (post_modify (reg) (plus (reg) (const_int))))
5185 	     => access location by using register which will be
5186 	     post modified with const_int,
5187 	     use "lbsi.bi/ lhsi.bi" */
5188 	  snprintf (pattern, sizeof (pattern), "l%csi.bi\t%%0, %%1", size);
5189 	  break;
5190 	default:
5191 	  abort ();
5192 	}
5193       break;
5194 
5195     case PLUS:
5196       switch (GET_CODE (XEXP (code, 1)))
5197 	{
5198 	case REG:
5199 	case SUBREG:
5200 	  /* (mem (plus reg reg)) or (mem (plus (mult reg const_int) reg))
5201 	     use "lbs / lhs" */
5202 	  snprintf (pattern, sizeof (pattern), "l%cs\t%%0, %%1", size);
5203 	  break;
5204 	case CONST_INT:
5205 	  /* (mem (plus reg const_int))
5206 	     => access location by adding one register with const_int,
5207 	     use "lbsi / lhsi" */
5208 	  snprintf (pattern, sizeof (pattern), "l%csi\t%%0, %%1", size);
5209 	  break;
5210 	default:
5211 	  abort ();
5212 	}
5213       break;
5214 
5215     case LO_SUM:
5216       operands[2] = XEXP (code, 1);
5217       operands[1] = XEXP (code, 0);
5218       snprintf (pattern, sizeof (pattern),
5219 		"l%csi\t%%0, [%%1 + lo12(%%2)]", size);
5220       break;
5221 
5222     default:
5223       abort ();
5224     }
5225 
5226   output_asm_insn (pattern, operands);
5227   return "";
5228 }
5229 
5230 /* Function to output stack push operation.
5231    We need to deal with normal stack push multiple or stack v3push.  */
5232 const char *
nds32_output_stack_push(void)5233 nds32_output_stack_push (void)
5234 {
5235   /* A string pattern for output_asm_insn().  */
5236   char pattern[100];
5237   /* The operands array which will be used in output_asm_insn().  */
5238   rtx operands[3];
5239   /* Pick up callee-saved first regno and last regno for further use.  */
5240   int rb_regno = cfun->machine->callee_saved_regs_first_regno;
5241   int re_regno = cfun->machine->callee_saved_regs_last_regno;
5242 
5243   if (TARGET_V3PUSH)
5244     {
5245       /* For stack v3push:
5246            operands[0]: Re
5247            operands[1]: imm8u */
5248 
5249       /* This variable is to check if 'push25 Re,imm8u' is available.  */
5250       int sp_adjust;
5251 
5252       /* Set operands[0].  */
5253       operands[0] = gen_rtx_REG (SImode, re_regno);
5254 
5255       /* Check if we can generate 'push25 Re,imm8u',
5256          otherwise, generate 'push25 Re,0'.  */
5257       sp_adjust = cfun->machine->local_size
5258 		  + cfun->machine->out_args_size
5259 		  + cfun->machine->callee_saved_area_padding_bytes;
5260       if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
5261 	  && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
5262 	operands[1] = GEN_INT (sp_adjust);
5263       else
5264 	operands[1] = GEN_INT (0);
5265 
5266       /* Create assembly code pattern.  */
5267       snprintf (pattern, sizeof (pattern), "push25\t%%0, %%1");
5268     }
5269   else
5270     {
5271       /* For normal stack push multiple:
5272          operands[0]: Rb
5273          operands[1]: Re
5274          operands[2]: En4 */
5275 
5276       /* This variable is used to check if we only need to generate En4 field.
5277          As long as Rb==Re=SP_REGNUM, we set this variable to 1.  */
5278       int push_en4_only_p = 0;
5279 
5280       /* Set operands[0] and operands[1].  */
5281       operands[0] = gen_rtx_REG (SImode, rb_regno);
5282       operands[1] = gen_rtx_REG (SImode, re_regno);
5283 
5284       /* 'smw.adm $sp,[$sp],$sp,0' means push nothing.  */
5285       if (!cfun->machine->fp_size
5286 	  && !cfun->machine->gp_size
5287 	  && !cfun->machine->lp_size
5288 	  && REGNO (operands[0]) == SP_REGNUM
5289 	  && REGNO (operands[1]) == SP_REGNUM)
5290 	{
5291 	  /* No need to generate instruction.  */
5292 	  return "";
5293 	}
5294       else
5295 	{
5296 	  /* If Rb==Re=SP_REGNUM, we only need to generate En4 field.  */
5297 	  if (REGNO (operands[0]) == SP_REGNUM
5298 	      && REGNO (operands[1]) == SP_REGNUM)
5299 	    push_en4_only_p = 1;
5300 
5301 	  /* Create assembly code pattern.
5302 	     We need to handle the form: "Rb, Re, { $fp $gp $lp }".  */
5303 	  snprintf (pattern, sizeof (pattern),
5304 		    "push.s\t%s{%s%s%s }",
5305 		    push_en4_only_p ? "" : "%0, %1, ",
5306 		    cfun->machine->fp_size ? " $fp" : "",
5307 		    cfun->machine->gp_size ? " $gp" : "",
5308 		    cfun->machine->lp_size ? " $lp" : "");
5309 	}
5310     }
5311 
5312   /* We use output_asm_insn() to output assembly code by ourself.  */
5313   output_asm_insn (pattern, operands);
5314   return "";
5315 }
5316 
5317 /* Function to output stack pop operation.
5318    We need to deal with normal stack pop multiple or stack v3pop.  */
5319 const char *
nds32_output_stack_pop(void)5320 nds32_output_stack_pop (void)
5321 {
5322   /* A string pattern for output_asm_insn().  */
5323   char pattern[100];
5324   /* The operands array which will be used in output_asm_insn().  */
5325   rtx operands[3];
5326   /* Pick up callee-saved first regno and last regno for further use.  */
5327   int rb_regno = cfun->machine->callee_saved_regs_first_regno;
5328   int re_regno = cfun->machine->callee_saved_regs_last_regno;
5329 
5330   if (TARGET_V3PUSH)
5331     {
5332       /* For stack v3pop:
5333            operands[0]: Re
5334            operands[1]: imm8u */
5335 
5336       /* This variable is to check if 'pop25 Re,imm8u' is available.  */
5337       int sp_adjust;
5338 
5339       /* Set operands[0].  */
5340       operands[0] = gen_rtx_REG (SImode, re_regno);
5341 
5342       /* Check if we can generate 'pop25 Re,imm8u',
5343          otherwise, generate 'pop25 Re,0'.
5344          We have to consider alloca issue as well.
5345          If the function does call alloca(), the stack pointer is not fixed.
5346          In that case, we cannot use 'pop25 Re,imm8u' directly.
5347          We have to caculate stack pointer from frame pointer
5348          and then use 'pop25 Re,0'.  */
5349       sp_adjust = cfun->machine->local_size
5350 		  + cfun->machine->out_args_size
5351 		  + cfun->machine->callee_saved_area_padding_bytes;
5352       if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
5353 	  && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
5354 	  && !cfun->calls_alloca)
5355 	operands[1] = GEN_INT (sp_adjust);
5356       else
5357 	operands[1] = GEN_INT (0);
5358 
5359       /* Create assembly code pattern.  */
5360       snprintf (pattern, sizeof (pattern), "pop25\t%%0, %%1");
5361     }
5362   else
5363     {
5364       /* For normal stack pop multiple:
5365          operands[0]: Rb
5366          operands[1]: Re
5367          operands[2]: En4 */
5368 
5369       /* This variable is used to check if we only need to generate En4 field.
5370          As long as Rb==Re=SP_REGNUM, we set this variable to 1.  */
5371       int pop_en4_only_p = 0;
5372 
5373       /* Set operands[0] and operands[1].  */
5374       operands[0] = gen_rtx_REG (SImode, rb_regno);
5375       operands[1] = gen_rtx_REG (SImode, re_regno);
5376 
5377       /* 'lmw.bim $sp,[$sp],$sp,0' means pop nothing.  */
5378       if (!cfun->machine->fp_size
5379 	  && !cfun->machine->gp_size
5380 	  && !cfun->machine->lp_size
5381 	  && REGNO (operands[0]) == SP_REGNUM
5382 	  && REGNO (operands[1]) == SP_REGNUM)
5383 	{
5384 	  /* No need to generate instruction.  */
5385 	  return "";
5386 	}
5387       else
5388 	{
5389 	  /* If Rb==Re=SP_REGNUM, we only need to generate En4 field.  */
5390 	  if (REGNO (operands[0]) == SP_REGNUM
5391 	      && REGNO (operands[1]) == SP_REGNUM)
5392 	    pop_en4_only_p = 1;
5393 
5394 	  /* Create assembly code pattern.
5395 	     We need to handle the form: "Rb, Re, { $fp $gp $lp }".  */
5396 	  snprintf (pattern, sizeof (pattern),
5397 		    "pop.s\t%s{%s%s%s }",
5398 		    pop_en4_only_p ? "" : "%0, %1, ",
5399 		    cfun->machine->fp_size ? " $fp" : "",
5400 		    cfun->machine->gp_size ? " $gp" : "",
5401 		    cfun->machine->lp_size ? " $lp" : "");
5402 	}
5403     }
5404 
5405   /* We use output_asm_insn() to output assembly code by ourself.  */
5406   output_asm_insn (pattern, operands);
5407   return "";
5408 }
5409 
5410 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte.  */
5411 int
nds32_target_alignment(rtx label)5412 nds32_target_alignment (rtx label)
5413 {
5414   rtx insn;
5415 
5416   if (optimize_size)
5417     return 0;
5418 
5419   insn = next_active_insn (label);
5420 
5421   if (insn == 0)
5422     return 0;
5423   else if ((get_attr_length (insn) % 4) == 0)
5424     return 2;
5425   else
5426     return 0;
5427 }
5428 
5429 /* ------------------------------------------------------------------------ */
5430 
5431 /* PART 5: Initialize target hook structure and definitions.  */
5432 
5433 /* Controlling the Compilation Driver.  */
5434 
5435 
5436 /* Run-time Target Specification.  */
5437 
5438 
5439 /* Defining Data Structures for Per-function Information.  */
5440 
5441 
5442 /* Storage Layout.  */
5443 
5444 #undef TARGET_PROMOTE_FUNCTION_MODE
5445 #define TARGET_PROMOTE_FUNCTION_MODE \
5446   default_promote_function_mode_always_promote
5447 
5448 
5449 /* Layout of Source Language Data Types.  */
5450 
5451 
5452 /* Register Usage.  */
5453 
5454 /* -- Basic Characteristics of Registers.  */
5455 
5456 /* -- Order of Allocation of Registers.  */
5457 
5458 /* -- How Values Fit in Registers.  */
5459 
5460 /* -- Handling Leaf Functions.  */
5461 
5462 /* -- Registers That Form a Stack.  */
5463 
5464 
5465 /* Register Classes.  */
5466 
5467 #undef TARGET_CLASS_MAX_NREGS
5468 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
5469 
5470 #undef TARGET_LRA_P
5471 #define TARGET_LRA_P hook_bool_void_true
5472 
5473 #undef TARGET_REGISTER_PRIORITY
5474 #define TARGET_REGISTER_PRIORITY nds32_register_priority
5475 
5476 
5477 /* Obsolete Macros for Defining Constraints.  */
5478 
5479 
5480 /* Stack Layout and Calling Conventions.  */
5481 
5482 /* -- Basic Stack Layout.  */
5483 
5484 /* -- Exception Handling Support.  */
5485 
5486 /* -- Specifying How Stack Checking is Done.  */
5487 
5488 /* -- Registers That Address the Stack Frame.  */
5489 
5490 /* -- Eliminating Frame Pointer and Arg Pointer.  */
5491 
5492 #undef TARGET_CAN_ELIMINATE
5493 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
5494 
5495 /* -- Passing Function Arguments on the Stack.  */
5496 
5497 /* -- Passing Arguments in Registers.  */
5498 
5499 #undef TARGET_FUNCTION_ARG
5500 #define TARGET_FUNCTION_ARG nds32_function_arg
5501 
5502 #undef TARGET_FUNCTION_ARG_ADVANCE
5503 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5504 
5505 #undef TARGET_FUNCTION_ARG_BOUNDARY
5506 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5507 
5508 /* -- How Scalar Function Values Are Returned.  */
5509 
5510 #undef TARGET_FUNCTION_VALUE
5511 #define TARGET_FUNCTION_VALUE nds32_function_value
5512 
5513 #undef TARGET_LIBCALL_VALUE
5514 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5515 
5516 #undef TARGET_FUNCTION_VALUE_REGNO_P
5517 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5518 
5519 /* -- How Large Values Are Returned.  */
5520 
5521 /* -- Caller-Saves Register Allocation.  */
5522 
5523 /* -- Function Entry and Exit.  */
5524 
5525 #undef TARGET_ASM_FUNCTION_PROLOGUE
5526 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5527 
5528 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5529 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5530 
5531 #undef  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5532 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5533 
5534 #undef TARGET_ASM_FUNCTION_EPILOGUE
5535 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5536 
5537 #undef TARGET_ASM_OUTPUT_MI_THUNK
5538 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5539 
5540 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5541 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5542 
5543 /* -- Generating Code for Profiling.  */
5544 
5545 /* -- Permitting tail calls.  */
5546 
5547 #undef TARGET_WARN_FUNC_RETURN
5548 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5549 
5550 /* Stack smashing protection.  */
5551 
5552 
5553 /* Implementing the Varargs Macros.  */
5554 
5555 #undef TARGET_STRICT_ARGUMENT_NAMING
5556 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5557 
5558 
5559 /* Trampolines for Nested Functions.  */
5560 
5561 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5562 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5563 
5564 #undef TARGET_TRAMPOLINE_INIT
5565 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5566 
5567 
5568 /* Implicit Calls to Library Routines.  */
5569 
5570 
5571 /* Addressing Modes.  */
5572 
5573 #undef TARGET_LEGITIMATE_ADDRESS_P
5574 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5575 
5576 
5577 /* Anchored Addresses.  */
5578 
5579 
5580 /* Condition Code Status.  */
5581 
5582 /* -- Representation of condition codes using (cc0).  */
5583 
5584 /* -- Representation of condition codes using registers.  */
5585 
5586 /* -- Macros to control conditional execution.  */
5587 
5588 
5589 /* Describing Relative Costs of Operations.  */
5590 
5591 #undef TARGET_REGISTER_MOVE_COST
5592 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5593 
5594 #undef TARGET_MEMORY_MOVE_COST
5595 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5596 
5597 #undef TARGET_RTX_COSTS
5598 #define TARGET_RTX_COSTS nds32_rtx_costs
5599 
5600 #undef TARGET_ADDRESS_COST
5601 #define TARGET_ADDRESS_COST nds32_address_cost
5602 
5603 
5604 /* Adjusting the Instruction Scheduler.  */
5605 
5606 
5607 /* Dividing the Output into Sections (Texts, Data, . . . ).  */
5608 
5609 
5610 /* Position Independent Code.  */
5611 
5612 
5613 /* Defining the Output Assembler Language.  */
5614 
5615 /* -- The Overall Framework of an Assembler File.  */
5616 
5617 #undef TARGET_ASM_FILE_START
5618 #define TARGET_ASM_FILE_START nds32_asm_file_start
5619 #undef TARGET_ASM_FILE_END
5620 #define TARGET_ASM_FILE_END nds32_asm_file_end
5621 
5622 /* -- Output of Data.  */
5623 
5624 #undef TARGET_ASM_ALIGNED_HI_OP
5625 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5626 
5627 #undef TARGET_ASM_ALIGNED_SI_OP
5628 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5629 
5630 /* -- Output of Uninitialized Variables.  */
5631 
5632 /* -- Output and Generation of Labels.  */
5633 
5634 #undef TARGET_ASM_GLOBALIZE_LABEL
5635 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5636 
5637 /* -- How Initialization Functions Are Handled.  */
5638 
5639 /* -- Macros Controlling Initialization Routines.  */
5640 
5641 /* -- Output of Assembler Instructions.  */
5642 
5643 #undef TARGET_PRINT_OPERAND
5644 #define TARGET_PRINT_OPERAND nds32_print_operand
5645 #undef TARGET_PRINT_OPERAND_ADDRESS
5646 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5647 
5648 /* -- Output of Dispatch Tables.  */
5649 
5650 /* -- Assembler Commands for Exception Regions.  */
5651 
5652 /* -- Assembler Commands for Alignment.  */
5653 
5654 
5655 /* Controlling Debugging Information Format.  */
5656 
5657 /* -- Macros Affecting All Debugging Formats.  */
5658 
5659 /* -- Specific Options for DBX Output.  */
5660 
5661 /* -- Open-Ended Hooks for DBX Format.  */
5662 
5663 /* -- File Names in DBX Format.  */
5664 
5665 /* -- Macros for SDB and DWARF Output.  */
5666 
5667 /* -- Macros for VMS Debug Format.  */
5668 
5669 
5670 /* Cross Compilation and Floating Point.  */
5671 
5672 
5673 /* Mode Switching Instructions.  */
5674 
5675 
5676 /* Defining target-specific uses of __attribute__.  */
5677 
5678 #undef TARGET_ATTRIBUTE_TABLE
5679 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5680 
5681 #undef TARGET_MERGE_DECL_ATTRIBUTES
5682 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5683 
5684 #undef TARGET_INSERT_ATTRIBUTES
5685 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5686 
5687 #undef TARGET_OPTION_PRAGMA_PARSE
5688 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5689 
5690 #undef TARGET_OPTION_OVERRIDE
5691 #define TARGET_OPTION_OVERRIDE nds32_option_override
5692 
5693 
5694 /* Emulating TLS.  */
5695 
5696 
5697 /* Defining coprocessor specifics for MIPS targets.  */
5698 
5699 
5700 /* Parameters for Precompiled Header Validity Checking.  */
5701 
5702 
5703 /* C++ ABI parameters.  */
5704 
5705 
5706 /* Adding support for named address spaces.  */
5707 
5708 
5709 /* Miscellaneous Parameters.  */
5710 
5711 #undef TARGET_INIT_BUILTINS
5712 #define TARGET_INIT_BUILTINS nds32_init_builtins
5713 
5714 #undef TARGET_EXPAND_BUILTIN
5715 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5716 
5717 
5718 /* ------------------------------------------------------------------------ */
5719 
5720 /* Initialize the GCC target structure.  */
5721 
5722 struct gcc_target targetm = TARGET_INITIALIZER;
5723 
5724 /* ------------------------------------------------------------------------ */
5725