]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nds32/nds32.c
28de0a6744ad2c81b05481463a061955ba1d2bf0
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.c
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 "hashtab.h"
42 #include "hash-set.h"
43 #include "vec.h"
44 #include "machmode.h"
45 #include "input.h"
46 #include "function.h"
47 #include "expr.h"
48 #include "recog.h"
49 #include "diagnostic-core.h"
50 #include "df.h"
51 #include "tm_p.h"
52 #include "tm-constrs.h"
53 #include "optabs.h" /* For GEN_FCN. */
54 #include "target.h"
55 #include "target-def.h"
56 #include "langhooks.h" /* For add_builtin_function(). */
57 #include "ggc.h"
58 #include "builtins.h"
59
60 /* ------------------------------------------------------------------------ */
61
62 /* This file is divided into five parts:
63
64 PART 1: Auxiliary static variable definitions and
65 target hook static variable definitions.
66
67 PART 2: Auxiliary static function definitions.
68
69 PART 3: Implement target hook stuff definitions.
70
71 PART 4: Implemet extern function definitions,
72 the prototype is in nds32-protos.h.
73
74 PART 5: Initialize target hook structure and definitions. */
75
76 /* ------------------------------------------------------------------------ */
77
78 /* PART 1: Auxiliary static variable definitions and
79 target hook static variable definitions. */
80
81 /* Define intrinsic register names.
82 Please refer to nds32_intrinsic.h file, the index is corresponding to
83 'enum nds32_intrinsic_registers' data type values.
84 NOTE that the base value starting from 1024. */
85 static const char * const nds32_intrinsic_register_names[] =
86 {
87 "$PSW", "$IPSW", "$ITYPE", "$IPC"
88 };
89
90 /* Defining target-specific uses of __attribute__. */
91 static const struct attribute_spec nds32_attribute_table[] =
92 {
93 /* Syntax: { name, min_len, max_len, decl_required, type_required,
94 function_type_required, handler, affects_type_identity } */
95
96 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
97 { "interrupt", 1, 64, false, false, false, NULL, false },
98 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
99 { "exception", 1, 8, false, false, false, NULL, false },
100 /* Argument is user's interrupt numbers. The vector number is always 0. */
101 { "reset", 1, 1, false, false, false, NULL, false },
102
103 /* The attributes describing isr nested type. */
104 { "nested", 0, 0, false, false, false, NULL, false },
105 { "not_nested", 0, 0, false, false, false, NULL, false },
106 { "nested_ready", 0, 0, false, false, false, NULL, false },
107
108 /* The attributes describing isr register save scheme. */
109 { "save_all", 0, 0, false, false, false, NULL, false },
110 { "partial_save", 0, 0, false, false, false, NULL, false },
111
112 /* The attributes used by reset attribute. */
113 { "nmi", 1, 1, false, false, false, NULL, false },
114 { "warm", 1, 1, false, false, false, NULL, false },
115
116 /* The attribute telling no prologue/epilogue. */
117 { "naked", 0, 0, false, false, false, NULL, false },
118
119 /* The last attribute spec is set to be NULL. */
120 { NULL, 0, 0, false, false, false, NULL, false }
121 };
122
123
124 /* ------------------------------------------------------------------------ */
125
126 /* PART 2: Auxiliary static function definitions. */
127
128 /* Function to save and restore machine-specific function data. */
129 static struct machine_function *
130 nds32_init_machine_status (void)
131 {
132 struct machine_function *machine;
133 machine = ggc_cleared_alloc<machine_function> ();
134
135 /* Initially assume this function needs prologue/epilogue. */
136 machine->naked_p = 0;
137
138 /* Initially assume this function does NOT use fp_as_gp optimization. */
139 machine->fp_as_gp_p = 0;
140
141 return machine;
142 }
143
144 /* Function to compute stack frame size and
145 store into cfun->machine structure. */
146 static void
147 nds32_compute_stack_frame (void)
148 {
149 int r;
150 int block_size;
151
152 /* Because nds32_compute_stack_frame() will be called from different place,
153 everytime we enter this function, we have to assume this function
154 needs prologue/epilogue. */
155 cfun->machine->naked_p = 0;
156
157 /* Get variadic arguments size to prepare pretend arguments and
158 we will push them into stack at prologue by ourself. */
159 cfun->machine->va_args_size = crtl->args.pretend_args_size;
160 if (cfun->machine->va_args_size != 0)
161 {
162 cfun->machine->va_args_first_regno
163 = NDS32_GPR_ARG_FIRST_REGNUM
164 + NDS32_MAX_GPR_REGS_FOR_ARGS
165 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
166 cfun->machine->va_args_last_regno
167 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
168 }
169 else
170 {
171 cfun->machine->va_args_first_regno = SP_REGNUM;
172 cfun->machine->va_args_last_regno = SP_REGNUM;
173 }
174
175 /* Important: We need to make sure that varargs area is 8-byte alignment. */
176 block_size = cfun->machine->va_args_size;
177 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
178 {
179 cfun->machine->va_args_area_padding_bytes
180 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
181 }
182
183 /* Get local variables, incoming variables, and temporary variables size.
184 Note that we need to make sure it is 8-byte alignment because
185 there may be no padding bytes if we are using LRA. */
186 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
187
188 /* Get outgoing arguments size. */
189 cfun->machine->out_args_size = crtl->outgoing_args_size;
190
191 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
192 Check whether $fp is ever live. */
193 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
194
195 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
196 Check whether we are using PIC code genration. */
197 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
198
199 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
200 Check whether $lp is ever live. */
201 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
202
203 /* Initially there is no padding bytes. */
204 cfun->machine->callee_saved_area_padding_bytes = 0;
205
206 /* Calculate the bytes of saving callee-saved registers on stack. */
207 cfun->machine->callee_saved_regs_size = 0;
208 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
209 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
210 /* Currently, there is no need to check $r28~$r31
211 because we will save them in another way. */
212 for (r = 0; r < 28; r++)
213 {
214 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
215 {
216 /* Mark the first required callee-saved register
217 (only need to set it once).
218 If first regno == SP_REGNUM, we can tell that
219 it is the first time to be here. */
220 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
221 cfun->machine->callee_saved_regs_first_regno = r;
222 /* Mark the last required callee-saved register. */
223 cfun->machine->callee_saved_regs_last_regno = r;
224 }
225 }
226
227 /* Check if this function can omit prologue/epilogue code fragment.
228 If there is 'naked' attribute in this function,
229 we can set 'naked_p' flag to indicate that
230 we do not have to generate prologue/epilogue.
231 Or, if all the following conditions succeed,
232 we can set this function 'naked_p' as well:
233 condition 1: first_regno == last_regno == SP_REGNUM,
234 which means we do not have to save
235 any callee-saved registers.
236 condition 2: Both $lp and $fp are NOT live in this function,
237 which means we do not need to save them and there
238 is no outgoing size.
239 condition 3: There is no local_size, which means
240 we do not need to adjust $sp. */
241 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
242 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
243 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
244 && !df_regs_ever_live_p (FP_REGNUM)
245 && !df_regs_ever_live_p (LP_REGNUM)
246 && cfun->machine->local_size == 0))
247 {
248 /* Set this function 'naked_p' and other functions can check this flag.
249 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
250 callee-saved, local size, and outgoing size.
251 The varargs space and ret instruction may still present in
252 the prologue/epilogue expanding. */
253 cfun->machine->naked_p = 1;
254
255 /* No need to save $fp, $gp, and $lp.
256 We should set these value to be zero
257 so that nds32_initial_elimination_offset() can work properly. */
258 cfun->machine->fp_size = 0;
259 cfun->machine->gp_size = 0;
260 cfun->machine->lp_size = 0;
261
262 /* If stack usage computation is required,
263 we need to provide the static stack size. */
264 if (flag_stack_usage_info)
265 current_function_static_stack_size = 0;
266
267 /* No need to do following adjustment, return immediately. */
268 return;
269 }
270
271 /* Adjustment for v3push instructions:
272 If we are using v3push (push25/pop25) instructions,
273 we need to make sure Rb is $r6 and Re is
274 located on $r6, $r8, $r10, or $r14.
275 Some results above will be discarded and recomputed.
276 Note that it is only available under V3/V3M ISA and we
277 DO NOT setup following stuff for isr or variadic function. */
278 if (TARGET_V3PUSH
279 && !nds32_isr_function_p (current_function_decl)
280 && (cfun->machine->va_args_size == 0))
281 {
282 /* Recompute:
283 cfun->machine->fp_size
284 cfun->machine->gp_size
285 cfun->machine->lp_size
286 cfun->machine->callee_saved_regs_first_regno
287 cfun->machine->callee_saved_regs_last_regno */
288
289 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
290 cfun->machine->fp_size = 4;
291 cfun->machine->gp_size = 4;
292 cfun->machine->lp_size = 4;
293
294 /* Remember to set Rb = $r6. */
295 cfun->machine->callee_saved_regs_first_regno = 6;
296
297 if (cfun->machine->callee_saved_regs_last_regno <= 6)
298 {
299 /* Re = $r6 */
300 cfun->machine->callee_saved_regs_last_regno = 6;
301 }
302 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
303 {
304 /* Re = $r8 */
305 cfun->machine->callee_saved_regs_last_regno = 8;
306 }
307 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
308 {
309 /* Re = $r10 */
310 cfun->machine->callee_saved_regs_last_regno = 10;
311 }
312 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
313 {
314 /* Re = $r14 */
315 cfun->machine->callee_saved_regs_last_regno = 14;
316 }
317 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
318 {
319 /* If last_regno is SP_REGNUM, which means
320 it is never changed, so set it to Re = $r6. */
321 cfun->machine->callee_saved_regs_last_regno = 6;
322 }
323 else
324 {
325 /* The program flow should not go here. */
326 gcc_unreachable ();
327 }
328 }
329
330 /* We have correctly set callee_saved_regs_first_regno
331 and callee_saved_regs_last_regno.
332 Initially, the callee_saved_regs_size is supposed to be 0.
333 As long as callee_saved_regs_last_regno is not SP_REGNUM,
334 we can update callee_saved_regs_size with new size. */
335 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
336 {
337 /* Compute pushed size of callee-saved registers. */
338 cfun->machine->callee_saved_regs_size
339 = 4 * (cfun->machine->callee_saved_regs_last_regno
340 - cfun->machine->callee_saved_regs_first_regno
341 + 1);
342 }
343
344 /* Important: We need to make sure that
345 (fp_size + gp_size + lp_size + callee_saved_regs_size)
346 is 8-byte alignment.
347 If it is not, calculate the padding bytes. */
348 block_size = cfun->machine->fp_size
349 + cfun->machine->gp_size
350 + cfun->machine->lp_size
351 + cfun->machine->callee_saved_regs_size;
352 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
353 {
354 cfun->machine->callee_saved_area_padding_bytes
355 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
356 }
357
358 /* If stack usage computation is required,
359 we need to provide the static stack size. */
360 if (flag_stack_usage_info)
361 {
362 current_function_static_stack_size
363 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
364 + cfun->machine->local_size
365 + cfun->machine->out_args_size;
366 }
367 }
368
369 /* Function to create a parallel rtx pattern
370 which presents stack push multiple behavior.
371 The overall concept are:
372 "push registers to memory",
373 "adjust stack pointer". */
374 static void
375 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4)
376 {
377 int regno;
378 int extra_count;
379 int num_use_regs;
380 int par_index;
381 int offset;
382 int save_fp, save_gp, save_lp;
383
384 rtx reg;
385 rtx mem;
386 rtx push_rtx;
387 rtx adjust_sp_rtx;
388 rtx parallel_insn;
389
390 /* We need to provide a customized rtx which contains
391 necessary information for data analysis,
392 so we create a parallel rtx like this:
393 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
394 (reg:SI Rb))
395 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
396 (reg:SI Rb+1))
397 ...
398 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
399 (reg:SI Re))
400 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
401 (reg:SI FP_REGNUM))
402 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
403 (reg:SI GP_REGNUM))
404 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
405 (reg:SI LP_REGNUM))
406 (set (reg:SI SP_REGNUM)
407 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
408
409 /* Determine whether we need to save $fp, $gp, or $lp. */
410 save_fp = INTVAL (En4) & 0x8;
411 save_gp = INTVAL (En4) & 0x4;
412 save_lp = INTVAL (En4) & 0x2;
413
414 /* Calculate the number of registers that will be pushed. */
415 extra_count = 0;
416 if (save_fp)
417 extra_count++;
418 if (save_gp)
419 extra_count++;
420 if (save_lp)
421 extra_count++;
422 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
423 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
424 num_use_regs = extra_count;
425 else
426 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
427
428 /* In addition to used registers,
429 we need one more space for (set sp sp-x) rtx. */
430 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
431 rtvec_alloc (num_use_regs + 1));
432 par_index = 0;
433
434 /* Initialize offset and start to create push behavior. */
435 offset = -(num_use_regs * 4);
436
437 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
438 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
439 {
440 /* Rb and Re may be SP_REGNUM.
441 We need to break this loop immediately. */
442 if (regno == SP_REGNUM)
443 break;
444
445 reg = gen_rtx_REG (SImode, regno);
446 mem = gen_frame_mem (SImode, plus_constant (Pmode,
447 stack_pointer_rtx,
448 offset));
449 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
450 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
451 RTX_FRAME_RELATED_P (push_rtx) = 1;
452 offset = offset + 4;
453 par_index++;
454 }
455
456 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
457 if (save_fp)
458 {
459 reg = gen_rtx_REG (SImode, FP_REGNUM);
460 mem = gen_frame_mem (SImode, plus_constant (Pmode,
461 stack_pointer_rtx,
462 offset));
463 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
464 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
465 RTX_FRAME_RELATED_P (push_rtx) = 1;
466 offset = offset + 4;
467 par_index++;
468 }
469 if (save_gp)
470 {
471 reg = gen_rtx_REG (SImode, GP_REGNUM);
472 mem = gen_frame_mem (SImode, plus_constant (Pmode,
473 stack_pointer_rtx,
474 offset));
475 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
476 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
477 RTX_FRAME_RELATED_P (push_rtx) = 1;
478 offset = offset + 4;
479 par_index++;
480 }
481 if (save_lp)
482 {
483 reg = gen_rtx_REG (SImode, LP_REGNUM);
484 mem = gen_frame_mem (SImode, plus_constant (Pmode,
485 stack_pointer_rtx,
486 offset));
487 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
488 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
489 RTX_FRAME_RELATED_P (push_rtx) = 1;
490 offset = offset + 4;
491 par_index++;
492 }
493
494 /* Create (set sp sp-x). */
495
496 /* We need to re-calculate the offset value again for adjustment. */
497 offset = -(num_use_regs * 4);
498 adjust_sp_rtx
499 = gen_rtx_SET (VOIDmode,
500 stack_pointer_rtx,
501 plus_constant (Pmode, stack_pointer_rtx, offset));
502 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
503 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
504
505 parallel_insn = emit_insn (parallel_insn);
506
507 /* The insn rtx 'parallel_insn' will change frame layout.
508 We need to use RTX_FRAME_RELATED_P so that GCC is able to
509 generate CFI (Call Frame Information) stuff. */
510 RTX_FRAME_RELATED_P (parallel_insn) = 1;
511 }
512
513 /* Function to create a parallel rtx pattern
514 which presents stack pop multiple behavior.
515 The overall concept are:
516 "pop registers from memory",
517 "adjust stack pointer". */
518 static void
519 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
520 {
521 int regno;
522 int extra_count;
523 int num_use_regs;
524 int par_index;
525 int offset;
526 int save_fp, save_gp, save_lp;
527
528 rtx reg;
529 rtx mem;
530 rtx pop_rtx;
531 rtx adjust_sp_rtx;
532 rtx parallel_insn;
533 rtx dwarf = NULL_RTX;
534
535 /* We need to provide a customized rtx which contains
536 necessary information for data analysis,
537 so we create a parallel rtx like this:
538 (parallel [(set (reg:SI Rb)
539 (mem (reg:SI SP_REGNUM)))
540 (set (reg:SI Rb+1)
541 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
542 ...
543 (set (reg:SI Re)
544 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
545 (set (reg:SI FP_REGNUM)
546 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
547 (set (reg:SI GP_REGNUM)
548 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
549 (set (reg:SI LP_REGNUM)
550 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
551 (set (reg:SI SP_REGNUM)
552 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
553
554 /* Determine whether we need to restore $fp, $gp, or $lp. */
555 save_fp = INTVAL (En4) & 0x8;
556 save_gp = INTVAL (En4) & 0x4;
557 save_lp = INTVAL (En4) & 0x2;
558
559 /* Calculate the number of registers that will be poped. */
560 extra_count = 0;
561 if (save_fp)
562 extra_count++;
563 if (save_gp)
564 extra_count++;
565 if (save_lp)
566 extra_count++;
567 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
568 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
569 num_use_regs = extra_count;
570 else
571 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
572
573 /* In addition to used registers,
574 we need one more space for (set sp sp+x) rtx. */
575 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
576 rtvec_alloc (num_use_regs + 1));
577 par_index = 0;
578
579 /* Initialize offset and start to create pop behavior. */
580 offset = 0;
581
582 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
583 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
584 {
585 /* Rb and Re may be SP_REGNUM.
586 We need to break this loop immediately. */
587 if (regno == SP_REGNUM)
588 break;
589
590 reg = gen_rtx_REG (SImode, regno);
591 mem = gen_frame_mem (SImode, plus_constant (Pmode,
592 stack_pointer_rtx,
593 offset));
594 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
595 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
596 RTX_FRAME_RELATED_P (pop_rtx) = 1;
597 offset = offset + 4;
598 par_index++;
599
600 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
601 }
602
603 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
604 if (save_fp)
605 {
606 reg = gen_rtx_REG (SImode, FP_REGNUM);
607 mem = gen_frame_mem (SImode, plus_constant (Pmode,
608 stack_pointer_rtx,
609 offset));
610 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
611 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
612 RTX_FRAME_RELATED_P (pop_rtx) = 1;
613 offset = offset + 4;
614 par_index++;
615
616 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
617 }
618 if (save_gp)
619 {
620 reg = gen_rtx_REG (SImode, GP_REGNUM);
621 mem = gen_frame_mem (SImode, plus_constant (Pmode,
622 stack_pointer_rtx,
623 offset));
624 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
625 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
626 RTX_FRAME_RELATED_P (pop_rtx) = 1;
627 offset = offset + 4;
628 par_index++;
629
630 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
631 }
632 if (save_lp)
633 {
634 reg = gen_rtx_REG (SImode, LP_REGNUM);
635 mem = gen_frame_mem (SImode, plus_constant (Pmode,
636 stack_pointer_rtx,
637 offset));
638 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
639 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
640 RTX_FRAME_RELATED_P (pop_rtx) = 1;
641 offset = offset + 4;
642 par_index++;
643
644 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
645 }
646
647 /* Create (set sp sp+x). */
648
649 /* The offset value is already in place. No need to re-calculate it. */
650 adjust_sp_rtx
651 = gen_rtx_SET (VOIDmode,
652 stack_pointer_rtx,
653 plus_constant (Pmode, stack_pointer_rtx, offset));
654 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
655
656 /* Tell gcc we adjust SP in this insn. */
657 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
658
659 parallel_insn = emit_insn (parallel_insn);
660
661 /* The insn rtx 'parallel_insn' will change frame layout.
662 We need to use RTX_FRAME_RELATED_P so that GCC is able to
663 generate CFI (Call Frame Information) stuff. */
664 RTX_FRAME_RELATED_P (parallel_insn) = 1;
665
666 /* Add CFI info by manual. */
667 REG_NOTES (parallel_insn) = dwarf;
668 }
669
670 /* Function to create a parallel rtx pattern
671 which presents stack v3push behavior.
672 The overall concept are:
673 "push registers to memory",
674 "adjust stack pointer". */
675 static void
676 nds32_emit_stack_v3push (rtx Rb,
677 rtx Re,
678 rtx En4 ATTRIBUTE_UNUSED,
679 rtx imm8u)
680 {
681 int regno;
682 int num_use_regs;
683 int par_index;
684 int offset;
685
686 rtx reg;
687 rtx mem;
688 rtx push_rtx;
689 rtx adjust_sp_rtx;
690 rtx parallel_insn;
691
692 /* We need to provide a customized rtx which contains
693 necessary information for data analysis,
694 so we create a parallel rtx like this:
695 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
696 (reg:SI Rb))
697 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
698 (reg:SI Rb+1))
699 ...
700 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
701 (reg:SI Re))
702 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
703 (reg:SI FP_REGNUM))
704 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
705 (reg:SI GP_REGNUM))
706 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
707 (reg:SI LP_REGNUM))
708 (set (reg:SI SP_REGNUM)
709 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
710
711 /* Calculate the number of registers that will be pushed.
712 Since $fp, $gp, and $lp is always pushed with v3push instruction,
713 we need to count these three registers.
714 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
715 So there is no need to worry about Rb=Re=SP_REGNUM case. */
716 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
717
718 /* In addition to used registers,
719 we need one more space for (set sp sp-x-imm8u) rtx. */
720 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
721 rtvec_alloc (num_use_regs + 1));
722 par_index = 0;
723
724 /* Initialize offset and start to create push behavior. */
725 offset = -(num_use_regs * 4);
726
727 /* Create (set mem regX) from Rb, Rb+1 up to Re.
728 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
729 So there is no need to worry about Rb=Re=SP_REGNUM case. */
730 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
731 {
732 reg = gen_rtx_REG (SImode, regno);
733 mem = gen_frame_mem (SImode, plus_constant (Pmode,
734 stack_pointer_rtx,
735 offset));
736 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
737 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
738 RTX_FRAME_RELATED_P (push_rtx) = 1;
739 offset = offset + 4;
740 par_index++;
741 }
742
743 /* Create (set mem fp). */
744 reg = gen_rtx_REG (SImode, FP_REGNUM);
745 mem = gen_frame_mem (SImode, plus_constant (Pmode,
746 stack_pointer_rtx,
747 offset));
748 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
749 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
750 RTX_FRAME_RELATED_P (push_rtx) = 1;
751 offset = offset + 4;
752 par_index++;
753 /* Create (set mem gp). */
754 reg = gen_rtx_REG (SImode, GP_REGNUM);
755 mem = gen_frame_mem (SImode, plus_constant (Pmode,
756 stack_pointer_rtx,
757 offset));
758 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
759 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
760 RTX_FRAME_RELATED_P (push_rtx) = 1;
761 offset = offset + 4;
762 par_index++;
763 /* Create (set mem lp). */
764 reg = gen_rtx_REG (SImode, LP_REGNUM);
765 mem = gen_frame_mem (SImode, plus_constant (Pmode,
766 stack_pointer_rtx,
767 offset));
768 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
769 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
770 RTX_FRAME_RELATED_P (push_rtx) = 1;
771 offset = offset + 4;
772 par_index++;
773
774 /* Create (set sp sp-x-imm8u). */
775
776 /* We need to re-calculate the offset value again for adjustment. */
777 offset = -(num_use_regs * 4);
778 adjust_sp_rtx
779 = gen_rtx_SET (VOIDmode,
780 stack_pointer_rtx,
781 plus_constant (Pmode,
782 stack_pointer_rtx,
783 offset - INTVAL (imm8u)));
784 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
785 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
786
787 parallel_insn = emit_insn (parallel_insn);
788
789 /* The insn rtx 'parallel_insn' will change frame layout.
790 We need to use RTX_FRAME_RELATED_P so that GCC is able to
791 generate CFI (Call Frame Information) stuff. */
792 RTX_FRAME_RELATED_P (parallel_insn) = 1;
793 }
794
795 /* Function to create a parallel rtx pattern
796 which presents stack v3pop behavior.
797 The overall concept are:
798 "pop registers from memory",
799 "adjust stack pointer". */
800 static void
801 nds32_emit_stack_v3pop (rtx Rb,
802 rtx Re,
803 rtx En4 ATTRIBUTE_UNUSED,
804 rtx imm8u)
805 {
806 int regno;
807 int num_use_regs;
808 int par_index;
809 int offset;
810
811 rtx reg;
812 rtx mem;
813 rtx pop_rtx;
814 rtx adjust_sp_rtx;
815 rtx parallel_insn;
816 rtx dwarf = NULL_RTX;
817
818 /* We need to provide a customized rtx which contains
819 necessary information for data analysis,
820 so we create a parallel rtx like this:
821 (parallel [(set (reg:SI Rb)
822 (mem (reg:SI SP_REGNUM)))
823 (set (reg:SI Rb+1)
824 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
825 ...
826 (set (reg:SI Re)
827 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
828 (set (reg:SI FP_REGNUM)
829 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
830 (set (reg:SI GP_REGNUM)
831 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
832 (set (reg:SI LP_REGNUM)
833 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
834 (set (reg:SI SP_REGNUM)
835 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
836
837 /* Calculate the number of registers that will be poped.
838 Since $fp, $gp, and $lp is always poped with v3pop instruction,
839 we need to count these three registers.
840 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
841 So there is no need to worry about Rb=Re=SP_REGNUM case. */
842 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
843
844 /* In addition to used registers,
845 we need one more space for (set sp sp+x+imm8u) rtx. */
846 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
847 rtvec_alloc (num_use_regs + 1));
848 par_index = 0;
849
850 /* Initialize offset and start to create pop behavior. */
851 offset = 0;
852
853 /* Create (set regX mem) from Rb, Rb+1 up to Re.
854 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
855 So there is no need to worry about Rb=Re=SP_REGNUM case. */
856 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
857 {
858 reg = gen_rtx_REG (SImode, regno);
859 mem = gen_frame_mem (SImode, plus_constant (Pmode,
860 stack_pointer_rtx,
861 offset));
862 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
863 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
864 RTX_FRAME_RELATED_P (pop_rtx) = 1;
865 offset = offset + 4;
866 par_index++;
867
868 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
869 }
870
871 /* Create (set fp mem). */
872 reg = gen_rtx_REG (SImode, FP_REGNUM);
873 mem = gen_frame_mem (SImode, plus_constant (Pmode,
874 stack_pointer_rtx,
875 offset));
876 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
877 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
878 RTX_FRAME_RELATED_P (pop_rtx) = 1;
879 offset = offset + 4;
880 par_index++;
881 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
882
883 /* Create (set gp mem). */
884 reg = gen_rtx_REG (SImode, GP_REGNUM);
885 mem = gen_frame_mem (SImode, plus_constant (Pmode,
886 stack_pointer_rtx,
887 offset));
888 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
889 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
890 RTX_FRAME_RELATED_P (pop_rtx) = 1;
891 offset = offset + 4;
892 par_index++;
893 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
894
895 /* Create (set lp mem ). */
896 reg = gen_rtx_REG (SImode, LP_REGNUM);
897 mem = gen_frame_mem (SImode, plus_constant (Pmode,
898 stack_pointer_rtx,
899 offset));
900 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
901 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
902 RTX_FRAME_RELATED_P (pop_rtx) = 1;
903 offset = offset + 4;
904 par_index++;
905 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
906
907 /* Create (set sp sp+x+imm8u). */
908
909 /* The offset value is already in place. No need to re-calculate it. */
910 adjust_sp_rtx
911 = gen_rtx_SET (VOIDmode,
912 stack_pointer_rtx,
913 plus_constant (Pmode,
914 stack_pointer_rtx,
915 offset + INTVAL (imm8u)));
916 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
917
918 /* Tell gcc we adjust SP in this insn. */
919 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
920
921 parallel_insn = emit_insn (parallel_insn);
922
923 /* The insn rtx 'parallel_insn' will change frame layout.
924 We need to use RTX_FRAME_RELATED_P so that GCC is able to
925 generate CFI (Call Frame Information) stuff. */
926 RTX_FRAME_RELATED_P (parallel_insn) = 1;
927
928 /* Add CFI info by manual. */
929 REG_NOTES (parallel_insn) = dwarf;
930 }
931
932 /* Function that may creates more instructions
933 for large value on adjusting stack pointer.
934
935 In nds32 target, 'addi' can be used for stack pointer
936 adjustment in prologue/epilogue stage.
937 However, sometimes there are too many local variables so that
938 the adjustment value is not able to be fit in the 'addi' instruction.
939 One solution is to move value into a register
940 and then use 'add' instruction.
941 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
942 Also, we need to return zero for sp adjustment so that
943 proglogue/epilogue knows there is no need to create 'addi' instruction. */
944 static int
945 nds32_force_addi_stack_int (int full_value)
946 {
947 int adjust_value;
948
949 rtx tmp_reg;
950 rtx sp_adjust_insn;
951
952 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
953 {
954 /* The value is not able to fit in single addi instruction.
955 Create more instructions of moving value into a register
956 and then add stack pointer with it. */
957
958 /* $r15 is going to be temporary register to hold the value. */
959 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
960
961 /* Create one more instruction to move value
962 into the temporary register. */
963 emit_move_insn (tmp_reg, GEN_INT (full_value));
964
965 /* Create new 'add' rtx. */
966 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
967 stack_pointer_rtx,
968 tmp_reg);
969 /* Emit rtx into insn list and receive its transformed insn rtx. */
970 sp_adjust_insn = emit_insn (sp_adjust_insn);
971
972 /* At prologue, we need to tell GCC that this is frame related insn,
973 so that we can consider this instruction to output debug information.
974 If full_value is NEGATIVE, it means this function
975 is invoked by expand_prologue. */
976 if (full_value < 0)
977 {
978 /* Because (tmp_reg <- full_value) may be split into two
979 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
980 We need to construct another (sp <- sp + full_value)
981 and then insert it into sp_adjust_insn's reg note to
982 represent a frame related expression.
983 GCC knows how to refer it and output debug information. */
984
985 rtx plus_rtx;
986 rtx set_rtx;
987
988 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
989 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
990 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
991
992 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
993 }
994
995 /* We have used alternative way to adjust stack pointer value.
996 Return zero so that prologue/epilogue
997 will not generate other instructions. */
998 return 0;
999 }
1000 else
1001 {
1002 /* The value is able to fit in addi instruction.
1003 However, remember to make it to be positive value
1004 because we want to return 'adjustment' result. */
1005 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1006
1007 return adjust_value;
1008 }
1009 }
1010
1011 /* Return true if MODE/TYPE need double word alignment. */
1012 static bool
1013 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
1014 {
1015 unsigned int align;
1016
1017 /* Pick up the alignment according to the mode or type. */
1018 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1019
1020 return (align > PARM_BOUNDARY);
1021 }
1022
1023 /* Return true if FUNC is a naked function. */
1024 static bool
1025 nds32_naked_function_p (tree func)
1026 {
1027 tree t;
1028
1029 if (TREE_CODE (func) != FUNCTION_DECL)
1030 abort ();
1031
1032 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1033
1034 return (t != NULL_TREE);
1035 }
1036
1037 /* Function that check if 'X' is a valid address register.
1038 The variable 'STRICT' is very important to
1039 make decision for register number.
1040
1041 STRICT : true
1042 => We are in reload pass or after reload pass.
1043 The register number should be strictly limited in general registers.
1044
1045 STRICT : false
1046 => Before reload pass, we are free to use any register number. */
1047 static bool
1048 nds32_address_register_rtx_p (rtx x, bool strict)
1049 {
1050 int regno;
1051
1052 if (GET_CODE (x) != REG)
1053 return false;
1054
1055 regno = REGNO (x);
1056
1057 if (strict)
1058 return REGNO_OK_FOR_BASE_P (regno);
1059 else
1060 return true;
1061 }
1062
1063 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1064
1065 OUTER_MODE : Machine mode of outer address rtx.
1066 INDEX : Check if this rtx is valid to be a index for address.
1067 STRICT : If it is true, we are in reload pass or after reload pass. */
1068 static bool
1069 nds32_legitimate_index_p (enum machine_mode outer_mode,
1070 rtx index,
1071 bool strict)
1072 {
1073 int regno;
1074 rtx op0;
1075 rtx op1;
1076
1077 switch (GET_CODE (index))
1078 {
1079 case REG:
1080 regno = REGNO (index);
1081 /* If we are in reload pass or after reload pass,
1082 we need to limit it to general register. */
1083 if (strict)
1084 return REGNO_OK_FOR_INDEX_P (regno);
1085 else
1086 return true;
1087
1088 case CONST_INT:
1089 /* The alignment of the integer value is determined by 'outer_mode'. */
1090 if (GET_MODE_SIZE (outer_mode) == 1)
1091 {
1092 /* Further check if the value is legal for the 'outer_mode'. */
1093 if (!satisfies_constraint_Is15 (index))
1094 return false;
1095
1096 /* Pass all test, the value is valid, return true. */
1097 return true;
1098 }
1099 if (GET_MODE_SIZE (outer_mode) == 2
1100 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1101 {
1102 /* Further check if the value is legal for the 'outer_mode'. */
1103 if (!satisfies_constraint_Is16 (index))
1104 return false;
1105
1106 /* Pass all test, the value is valid, return true. */
1107 return true;
1108 }
1109 if (GET_MODE_SIZE (outer_mode) == 4
1110 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1111 {
1112 /* Further check if the value is legal for the 'outer_mode'. */
1113 if (!satisfies_constraint_Is17 (index))
1114 return false;
1115
1116 /* Pass all test, the value is valid, return true. */
1117 return true;
1118 }
1119 if (GET_MODE_SIZE (outer_mode) == 8
1120 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1121 {
1122 /* Further check if the value is legal for the 'outer_mode'. */
1123 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1124 SImode)))
1125 return false;
1126
1127 /* Pass all test, the value is valid, return true. */
1128 return true;
1129 }
1130
1131 return false;
1132
1133 case MULT:
1134 op0 = XEXP (index, 0);
1135 op1 = XEXP (index, 1);
1136
1137 if (REG_P (op0) && CONST_INT_P (op1))
1138 {
1139 int multiplier;
1140 multiplier = INTVAL (op1);
1141
1142 /* We only allow (mult reg const_int_1)
1143 or (mult reg const_int_2) or (mult reg const_int_4). */
1144 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1145 return false;
1146
1147 regno = REGNO (op0);
1148 /* Limit it in general registers if we are
1149 in reload pass or after reload pass. */
1150 if(strict)
1151 return REGNO_OK_FOR_INDEX_P (regno);
1152 else
1153 return true;
1154 }
1155
1156 return false;
1157
1158 case ASHIFT:
1159 op0 = XEXP (index, 0);
1160 op1 = XEXP (index, 1);
1161
1162 if (REG_P (op0) && CONST_INT_P (op1))
1163 {
1164 int sv;
1165 /* op1 is already the sv value for use to do left shift. */
1166 sv = INTVAL (op1);
1167
1168 /* We only allow (ashift reg const_int_0)
1169 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1170 if (sv != 0 && sv != 1 && sv !=2)
1171 return false;
1172
1173 regno = REGNO (op0);
1174 /* Limit it in general registers if we are
1175 in reload pass or after reload pass. */
1176 if(strict)
1177 return REGNO_OK_FOR_INDEX_P (regno);
1178 else
1179 return true;
1180 }
1181
1182 return false;
1183
1184 default:
1185 return false;
1186 }
1187 }
1188
1189 /* ------------------------------------------------------------------------ */
1190
1191 /* PART 3: Implement target hook stuff definitions. */
1192 \f
1193 /* Register Classes. */
1194
1195 static unsigned char
1196 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1197 enum machine_mode mode)
1198 {
1199 /* Return the maximum number of consecutive registers
1200 needed to represent "mode" in a register of "rclass". */
1201 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1202 }
1203
1204 static int
1205 nds32_register_priority (int hard_regno)
1206 {
1207 /* Encourage to use r0-r7 for LRA when optimize for size. */
1208 if (optimize_size && hard_regno < 8)
1209 return 4;
1210 return 3;
1211 }
1212
1213 \f
1214 /* Stack Layout and Calling Conventions. */
1215
1216 /* There are three kinds of pointer concepts using in GCC compiler:
1217
1218 frame pointer: A pointer to the first location of local variables.
1219 stack pointer: A pointer to the top of a stack frame.
1220 argument pointer: A pointer to the incoming arguments.
1221
1222 In nds32 target calling convention, we are using 8-byte alignment.
1223 Besides, we would like to have each stack frame of a function includes:
1224
1225 [Block A]
1226 1. previous hard frame pointer
1227 2. return address
1228 3. callee-saved registers
1229 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1230 and save it at
1231 cfun->machine->callee_saved_area_padding_bytes)
1232
1233 [Block B]
1234 1. local variables
1235 2. spilling location
1236 3. <padding bytes> (it will be calculated by GCC itself)
1237 4. incoming arguments
1238 5. <padding bytes> (it will be calculated by GCC itself)
1239
1240 [Block C]
1241 1. <padding bytes> (it will be calculated by GCC itself)
1242 2. outgoing arguments
1243
1244 We 'wrap' these blocks together with
1245 hard frame pointer ($r28) and stack pointer ($r31).
1246 By applying the basic frame/stack/argument pointers concept,
1247 the layout of a stack frame shoule be like this:
1248
1249 | |
1250 old stack pointer -> ----
1251 | | \
1252 | | saved arguments for
1253 | | vararg functions
1254 | | /
1255 hard frame pointer -> --
1256 & argument pointer | | \
1257 | | previous hardware frame pointer
1258 | | return address
1259 | | callee-saved registers
1260 | | /
1261 frame pointer -> --
1262 | | \
1263 | | local variables
1264 | | and incoming arguments
1265 | | /
1266 --
1267 | | \
1268 | | outgoing
1269 | | arguments
1270 | | /
1271 stack pointer -> ----
1272
1273 $SFP and $AP are used to represent frame pointer and arguments pointer,
1274 which will be both eliminated as hard frame pointer. */
1275
1276 /* -- Eliminating Frame Pointer and Arg Pointer. */
1277
1278 static bool
1279 nds32_can_eliminate (const int from_reg, const int to_reg)
1280 {
1281 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1282 return true;
1283
1284 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1285 return true;
1286
1287 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1288 return true;
1289
1290 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1291 return true;
1292
1293 return false;
1294 }
1295
1296 /* -- Passing Arguments in Registers. */
1297
1298 static rtx
1299 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1300 const_tree type, bool named)
1301 {
1302 unsigned int regno;
1303 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1304
1305 /* The last time this hook is called,
1306 it is called with MODE == VOIDmode. */
1307 if (mode == VOIDmode)
1308 return NULL_RTX;
1309
1310 /* For nameless arguments, we need to take care it individually. */
1311 if (!named)
1312 {
1313 /* If we are under hard float abi, we have arguments passed on the
1314 stack and all situation can be handled by GCC itself. */
1315 if (TARGET_HARD_FLOAT)
1316 return NULL_RTX;
1317
1318 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1319 {
1320 /* If we still have enough registers to pass argument, pick up
1321 next available register number. */
1322 regno
1323 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1324 return gen_rtx_REG (mode, regno);
1325 }
1326
1327 /* No register available, return NULL_RTX.
1328 The compiler will use stack to pass argument instead. */
1329 return NULL_RTX;
1330 }
1331
1332 /* The following is to handle named argument.
1333 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1334 are different. */
1335 if (TARGET_HARD_FLOAT)
1336 {
1337 /* Currently we have not implemented hard float yet. */
1338 gcc_unreachable ();
1339 }
1340 else
1341 {
1342 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1343 argument. Since we allow to pass argument partially in registers,
1344 we can just return it if there are still registers available. */
1345 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1346 {
1347 /* Pick up the next available register number. */
1348 regno
1349 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1350 return gen_rtx_REG (mode, regno);
1351 }
1352
1353 }
1354
1355 /* No register available, return NULL_RTX.
1356 The compiler will use stack to pass argument instead. */
1357 return NULL_RTX;
1358 }
1359
1360 static bool
1361 nds32_must_pass_in_stack (enum machine_mode mode, const_tree type)
1362 {
1363 /* Return true if a type must be passed in memory.
1364 If it is NOT using hard float abi, small aggregates can be
1365 passed in a register even we are calling a variadic function.
1366 So there is no need to take padding into consideration. */
1367 if (TARGET_HARD_FLOAT)
1368 return must_pass_in_stack_var_size_or_pad (mode, type);
1369 else
1370 return must_pass_in_stack_var_size (mode, type);
1371 }
1372
1373 static int
1374 nds32_arg_partial_bytes (cumulative_args_t ca, enum machine_mode mode,
1375 tree type, bool named ATTRIBUTE_UNUSED)
1376 {
1377 /* Returns the number of bytes at the beginning of an argument that
1378 must be put in registers. The value must be zero for arguments that are
1379 passed entirely in registers or that are entirely pushed on the stack.
1380 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1381 first register to be used by the caller for this argument. */
1382 unsigned int needed_reg_count;
1383 unsigned int remaining_reg_count;
1384 CUMULATIVE_ARGS *cum;
1385
1386 cum = get_cumulative_args (ca);
1387
1388 /* Under hard float abi, we better have argument entirely passed in
1389 registers or pushed on the stack so that we can reduce the complexity
1390 of dealing with cum->gpr_offset and cum->fpr_offset. */
1391 if (TARGET_HARD_FLOAT)
1392 return 0;
1393
1394 /* If we have already runned out of argument registers, return zero
1395 so that the argument will be entirely pushed on the stack. */
1396 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1397 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1398 return 0;
1399
1400 /* Calculate how many registers do we need for this argument. */
1401 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1402
1403 /* Calculate how many argument registers have left for passing argument.
1404 Note that we should count it from next available register number. */
1405 remaining_reg_count
1406 = NDS32_MAX_GPR_REGS_FOR_ARGS
1407 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1408 - NDS32_GPR_ARG_FIRST_REGNUM);
1409
1410 /* Note that we have to return the nubmer of bytes, not registers count. */
1411 if (needed_reg_count > remaining_reg_count)
1412 return remaining_reg_count * UNITS_PER_WORD;
1413
1414 return 0;
1415 }
1416
1417 static void
1418 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1419 const_tree type, bool named)
1420 {
1421 enum machine_mode sub_mode;
1422 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1423
1424 if (named)
1425 {
1426 /* We need to further check TYPE and MODE so that we can determine
1427 which kind of register we shall advance. */
1428 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1429 sub_mode = TYPE_MODE (TREE_TYPE (type));
1430 else
1431 sub_mode = mode;
1432
1433 /* Under hard float abi, we may advance FPR registers. */
1434 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1435 {
1436 /* Currently we have not implemented hard float yet. */
1437 gcc_unreachable ();
1438 }
1439 else
1440 {
1441 cum->gpr_offset
1442 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1443 - NDS32_GPR_ARG_FIRST_REGNUM
1444 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1445 }
1446 }
1447 else
1448 {
1449 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1450 we can advance next register as well so that caller is
1451 able to pass arguments in registers and callee must be
1452 in charge of pushing all of them into stack. */
1453 if (!TARGET_HARD_FLOAT)
1454 {
1455 cum->gpr_offset
1456 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1457 - NDS32_GPR_ARG_FIRST_REGNUM
1458 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1459 }
1460 }
1461 }
1462
1463 static unsigned int
1464 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1465 {
1466 return (nds32_needs_double_word_align (mode, type)
1467 ? NDS32_DOUBLE_WORD_ALIGNMENT
1468 : PARM_BOUNDARY);
1469 }
1470
1471 /* -- How Scalar Function Values Are Returned. */
1472
1473 static rtx
1474 nds32_function_value (const_tree ret_type,
1475 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1476 bool outgoing ATTRIBUTE_UNUSED)
1477 {
1478 enum machine_mode mode;
1479 int unsignedp;
1480
1481 mode = TYPE_MODE (ret_type);
1482 unsignedp = TYPE_UNSIGNED (ret_type);
1483
1484 mode = promote_mode (ret_type, mode, &unsignedp);
1485
1486 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1487 }
1488
1489 static rtx
1490 nds32_libcall_value (enum machine_mode mode,
1491 const_rtx fun ATTRIBUTE_UNUSED)
1492 {
1493 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1494 }
1495
1496 static bool
1497 nds32_function_value_regno_p (const unsigned int regno)
1498 {
1499 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1500 }
1501
1502 /* -- Function Entry and Exit. */
1503
1504 /* The content produced from this function
1505 will be placed before prologue body. */
1506 static void
1507 nds32_asm_function_prologue (FILE *file,
1508 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1509 {
1510 int r;
1511 const char *func_name;
1512 tree attrs;
1513 tree name;
1514
1515 /* All stack frame information is supposed to be
1516 already computed when expanding prologue.
1517 The result is in cfun->machine.
1518 DO NOT call nds32_compute_stack_frame() here
1519 because it may corrupt the essential information. */
1520
1521 fprintf (file, "\t! BEGIN PROLOGUE\n");
1522 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1523 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1524 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1525 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1526
1527 /* Use df_regs_ever_live_p() to detect if the register
1528 is ever used in the current function. */
1529 fprintf (file, "\t! registers ever_live: ");
1530 for (r = 0; r < 32; r++)
1531 {
1532 if (df_regs_ever_live_p (r))
1533 fprintf (file, "%s, ", reg_names[r]);
1534 }
1535 fputc ('\n', file);
1536
1537 /* Display the attributes of this function. */
1538 fprintf (file, "\t! function attributes: ");
1539 /* Get the attributes tree list.
1540 Note that GCC builds attributes list with reverse order. */
1541 attrs = DECL_ATTRIBUTES (current_function_decl);
1542
1543 /* If there is no any attribute, print out "None". */
1544 if (!attrs)
1545 fprintf (file, "None");
1546
1547 /* If there are some attributes, try if we need to
1548 construct isr vector information. */
1549 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1550 nds32_construct_isr_vectors_information (attrs, func_name);
1551
1552 /* Display all attributes of this function. */
1553 while (attrs)
1554 {
1555 name = TREE_PURPOSE (attrs);
1556 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1557
1558 /* Pick up the next attribute. */
1559 attrs = TREE_CHAIN (attrs);
1560 }
1561 fputc ('\n', file);
1562 }
1563
1564 /* After rtl prologue has been expanded, this function is used. */
1565 static void
1566 nds32_asm_function_end_prologue (FILE *file)
1567 {
1568 fprintf (file, "\t! END PROLOGUE\n");
1569
1570 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1571 we can generate special directive: ".omit_fp_begin"
1572 to guide linker doing fp-as-gp optimization.
1573 However, for a naked function, which means
1574 it should not have prologue/epilogue,
1575 using fp-as-gp still requires saving $fp by push/pop behavior and
1576 there is no benefit to use fp-as-gp on such small function.
1577 So we need to make sure this function is NOT naked as well. */
1578 if (!frame_pointer_needed
1579 && !cfun->machine->naked_p
1580 && cfun->machine->fp_as_gp_p)
1581 {
1582 fprintf (file, "\t! ----------------------------------------\n");
1583 fprintf (file, "\t! Guide linker to do "
1584 "link time optimization: fp-as-gp\n");
1585 fprintf (file, "\t! We add one more instruction to "
1586 "initialize $fp near to $gp location.\n");
1587 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1588 fprintf (file, "\t! this extra instruction should be "
1589 "eliminated at link stage.\n");
1590 fprintf (file, "\t.omit_fp_begin\n");
1591 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1592 fprintf (file, "\t! ----------------------------------------\n");
1593 }
1594 }
1595
1596 /* Before rtl epilogue has been expanded, this function is used. */
1597 static void
1598 nds32_asm_function_begin_epilogue (FILE *file)
1599 {
1600 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1601 we can generate special directive: ".omit_fp_end"
1602 to claim fp-as-gp optimization range.
1603 However, for a naked function,
1604 which means it should not have prologue/epilogue,
1605 using fp-as-gp still requires saving $fp by push/pop behavior and
1606 there is no benefit to use fp-as-gp on such small function.
1607 So we need to make sure this function is NOT naked as well. */
1608 if (!frame_pointer_needed
1609 && !cfun->machine->naked_p
1610 && cfun->machine->fp_as_gp_p)
1611 {
1612 fprintf (file, "\t! ----------------------------------------\n");
1613 fprintf (file, "\t! Claim the range of fp-as-gp "
1614 "link time optimization\n");
1615 fprintf (file, "\t.omit_fp_end\n");
1616 fprintf (file, "\t! ----------------------------------------\n");
1617 }
1618
1619 fprintf (file, "\t! BEGIN EPILOGUE\n");
1620 }
1621
1622 /* The content produced from this function
1623 will be placed after epilogue body. */
1624 static void
1625 nds32_asm_function_epilogue (FILE *file,
1626 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1627 {
1628 fprintf (file, "\t! END EPILOGUE\n");
1629 }
1630
1631 static void
1632 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1633 HOST_WIDE_INT delta,
1634 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1635 tree function)
1636 {
1637 int this_regno;
1638
1639 /* Make sure unwind info is emitted for the thunk if needed. */
1640 final_start_function (emit_barrier (), file, 1);
1641
1642 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1643 ? 1
1644 : 0);
1645
1646 if (delta != 0)
1647 {
1648 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1649 {
1650 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1651 this_regno, this_regno, delta);
1652 }
1653 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1654 {
1655 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1656 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1657 }
1658 else
1659 {
1660 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1661 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1662 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1663 }
1664 }
1665
1666 fprintf (file, "\tb\t");
1667 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1668 fprintf (file, "\n");
1669
1670 final_end_function ();
1671 }
1672
1673 /* -- Permitting tail calls. */
1674
1675 /* Determine whether we need to enable warning for function return check. */
1676 static bool
1677 nds32_warn_func_return (tree decl)
1678 {
1679 /* Naked functions are implemented entirely in assembly, including the
1680 return sequence, so suppress warnings about this. */
1681 return !nds32_naked_function_p (decl);
1682 }
1683
1684 \f
1685 /* Implementing the Varargs Macros. */
1686
1687 static void
1688 nds32_setup_incoming_varargs (cumulative_args_t ca,
1689 enum machine_mode mode,
1690 tree type,
1691 int *pretend_args_size,
1692 int second_time ATTRIBUTE_UNUSED)
1693 {
1694 unsigned int total_args_regs;
1695 unsigned int num_of_used_regs;
1696 unsigned int remaining_reg_count;
1697 CUMULATIVE_ARGS *cum;
1698
1699 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1700 So that all nameless arguments are pushed by caller and all situation
1701 can be handled by GCC itself. */
1702 if (TARGET_HARD_FLOAT)
1703 return;
1704
1705 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1706 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1707 However, for nameless(anonymous) arguments, we should push them on the
1708 stack so that all the nameless arguments appear to have been passed
1709 consecutively in the memory for accessing. Hence, we need to check and
1710 exclude the registers that are used for named arguments. */
1711
1712 cum = get_cumulative_args (ca);
1713
1714 /* The MODE and TYPE describe the last argument.
1715 We need those information to determine the remaining registers
1716 for varargs. */
1717 total_args_regs
1718 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1719 num_of_used_regs
1720 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1721 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1722
1723 remaining_reg_count = total_args_regs - num_of_used_regs;
1724 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1725
1726 return;
1727 }
1728
1729 static bool
1730 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1731 {
1732 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1733 true for named arguments, and false for unnamed arguments. */
1734 return true;
1735 }
1736
1737 \f
1738 /* Trampolines for Nested Functions. */
1739
1740 static void
1741 nds32_asm_trampoline_template (FILE *f)
1742 {
1743 if (TARGET_REDUCED_REGS)
1744 {
1745 /* Trampoline is not supported on reduced-set registers yet. */
1746 sorry ("a nested function is not supported for reduced registers");
1747 }
1748 else
1749 {
1750 asm_fprintf (f, "\t! Trampoline code template\n");
1751 asm_fprintf (f, "\t! This code fragment will be copied "
1752 "into stack on demand\n");
1753
1754 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1755 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1756 "! load nested function address\n");
1757 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1758 "! load chain_value\n");
1759 asm_fprintf (f, "\tjr\t$r15\n");
1760 }
1761
1762 /* Preserve space ($pc + 16) for saving chain_value,
1763 nds32_trampoline_init will fill the value in this slot. */
1764 asm_fprintf (f, "\t! space for saving chain_value\n");
1765 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1766
1767 /* Preserve space ($pc + 20) for saving nested function address,
1768 nds32_trampoline_init will fill the value in this slot. */
1769 asm_fprintf (f, "\t! space for saving nested function address\n");
1770 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1771 }
1772
1773 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1774 static void
1775 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1776 {
1777 int i;
1778
1779 /* Nested function address. */
1780 rtx fnaddr;
1781 /* The memory rtx that is going to
1782 be filled with chain_value. */
1783 rtx chain_value_mem;
1784 /* The memory rtx that is going to
1785 be filled with nested function address. */
1786 rtx nested_func_mem;
1787
1788 /* Start address of trampoline code in stack, for doing cache sync. */
1789 rtx sync_cache_addr;
1790 /* Temporary register for sync instruction. */
1791 rtx tmp_reg;
1792 /* Instruction-cache sync instruction,
1793 requesting an argument as starting address. */
1794 rtx isync_insn;
1795 /* For convenience reason of doing comparison. */
1796 int tramp_align_in_bytes;
1797
1798 /* Trampoline is not supported on reduced-set registers yet. */
1799 if (TARGET_REDUCED_REGS)
1800 sorry ("a nested function is not supported for reduced registers");
1801
1802 /* STEP 1: Copy trampoline code template into stack,
1803 fill up essential data into stack. */
1804
1805 /* Extract nested function address rtx. */
1806 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1807
1808 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1809 We have nds32_asm_trampoline_template() to emit template pattern. */
1810 emit_block_move (m_tramp, assemble_trampoline_template (),
1811 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1812
1813 /* After copying trampoline code into stack,
1814 fill chain_value into stack. */
1815 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1816 emit_move_insn (chain_value_mem, chain_value);
1817 /* After copying trampoline code int stack,
1818 fill nested function address into stack. */
1819 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1820 emit_move_insn (nested_func_mem, fnaddr);
1821
1822 /* STEP 2: Sync instruction-cache. */
1823
1824 /* We have successfully filled trampoline code into stack.
1825 However, in order to execute code in stack correctly,
1826 we must sync instruction cache. */
1827 sync_cache_addr = XEXP (m_tramp, 0);
1828 tmp_reg = gen_reg_rtx (SImode);
1829 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1830
1831 /* Because nds32_cache_block_size is in bytes,
1832 we get trampoline alignment in bytes for convenient comparison. */
1833 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1834
1835 if (tramp_align_in_bytes >= nds32_cache_block_size
1836 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1837 {
1838 /* Under this condition, the starting address of trampoline
1839 must be aligned to the starting address of each cache block
1840 and we do not have to worry about cross-boundary issue. */
1841 for (i = 0;
1842 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1843 / nds32_cache_block_size;
1844 i++)
1845 {
1846 emit_move_insn (tmp_reg,
1847 plus_constant (Pmode, sync_cache_addr,
1848 nds32_cache_block_size * i));
1849 emit_insn (isync_insn);
1850 }
1851 }
1852 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1853 {
1854 /* The starting address of trampoline code
1855 may not be aligned to the cache block,
1856 so the trampoline code may be across two cache block.
1857 We need to sync the last element, which is 4-byte size,
1858 of trampoline template. */
1859 for (i = 0;
1860 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1861 / nds32_cache_block_size;
1862 i++)
1863 {
1864 emit_move_insn (tmp_reg,
1865 plus_constant (Pmode, sync_cache_addr,
1866 nds32_cache_block_size * i));
1867 emit_insn (isync_insn);
1868 }
1869
1870 /* The last element of trampoline template is 4-byte size. */
1871 emit_move_insn (tmp_reg,
1872 plus_constant (Pmode, sync_cache_addr,
1873 TRAMPOLINE_SIZE - 4));
1874 emit_insn (isync_insn);
1875 }
1876 else
1877 {
1878 /* This is the simplest case.
1879 Because TRAMPOLINE_SIZE is less than or
1880 equal to nds32_cache_block_size,
1881 we can just sync start address and
1882 the last element of trampoline code. */
1883
1884 /* Sync starting address of tampoline code. */
1885 emit_move_insn (tmp_reg, sync_cache_addr);
1886 emit_insn (isync_insn);
1887 /* Sync the last element, which is 4-byte size,
1888 of trampoline template. */
1889 emit_move_insn (tmp_reg,
1890 plus_constant (Pmode, sync_cache_addr,
1891 TRAMPOLINE_SIZE - 4));
1892 emit_insn (isync_insn);
1893 }
1894
1895 /* Set instruction serialization barrier
1896 to guarantee the correct operations. */
1897 emit_insn (gen_unspec_volatile_isb ());
1898 }
1899
1900 \f
1901 /* Addressing Modes. */
1902
1903 static bool
1904 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1905 {
1906 /* For (mem:DI addr) or (mem:DF addr) case,
1907 we only allow 'addr' to be [reg], [symbol_ref],
1908 [const], or [reg + const_int] pattern. */
1909 if (mode == DImode || mode == DFmode)
1910 {
1911 /* Allow [Reg + const_int] addressing mode. */
1912 if (GET_CODE (x) == PLUS)
1913 {
1914 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1915 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1916 && CONST_INT_P (XEXP (x, 1)))
1917 return true;
1918
1919 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1920 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1921 && CONST_INT_P (XEXP (x, 0)))
1922 return true;
1923 }
1924
1925 /* Now check [reg], [symbol_ref], and [const]. */
1926 if (GET_CODE (x) != REG
1927 && GET_CODE (x) != SYMBOL_REF
1928 && GET_CODE (x) != CONST)
1929 return false;
1930 }
1931
1932 /* Check if 'x' is a valid address. */
1933 switch (GET_CODE (x))
1934 {
1935 case REG:
1936 /* (mem (reg A)) => [Ra] */
1937 return nds32_address_register_rtx_p (x, strict);
1938
1939 case SYMBOL_REF:
1940
1941 if (!TARGET_GP_DIRECT
1942 && (reload_completed
1943 || reload_in_progress
1944 || lra_in_progress))
1945 return false;
1946
1947 /* (mem (symbol_ref A)) => [symbol_ref] */
1948 return !currently_expanding_to_rtl;
1949
1950 case CONST:
1951
1952 if (!TARGET_GP_DIRECT
1953 && (reload_completed
1954 || reload_in_progress
1955 || lra_in_progress))
1956 return false;
1957
1958 /* (mem (const (...)))
1959 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1960 if (GET_CODE (XEXP (x, 0)) == PLUS)
1961 {
1962 rtx plus_op = XEXP (x, 0);
1963
1964 rtx op0 = XEXP (plus_op, 0);
1965 rtx op1 = XEXP (plus_op, 1);
1966
1967 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1968 return true;
1969 else
1970 return false;
1971 }
1972
1973 return false;
1974
1975 case POST_MODIFY:
1976 /* (mem (post_modify (reg) (plus (reg) (reg))))
1977 => [Ra], Rb */
1978 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1979 => [Ra], const_int */
1980 if (GET_CODE (XEXP (x, 0)) == REG
1981 && GET_CODE (XEXP (x, 1)) == PLUS)
1982 {
1983 rtx plus_op = XEXP (x, 1);
1984
1985 rtx op0 = XEXP (plus_op, 0);
1986 rtx op1 = XEXP (plus_op, 1);
1987
1988 if (nds32_address_register_rtx_p (op0, strict)
1989 && nds32_legitimate_index_p (mode, op1, strict))
1990 return true;
1991 else
1992 return false;
1993 }
1994
1995 return false;
1996
1997 case POST_INC:
1998 case POST_DEC:
1999 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2000 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2001 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2002 We only need to deal with register Ra. */
2003 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2004 return true;
2005 else
2006 return false;
2007
2008 case PLUS:
2009 /* (mem (plus reg const_int))
2010 => [Ra + imm] */
2011 /* (mem (plus reg reg))
2012 => [Ra + Rb] */
2013 /* (mem (plus (mult reg const_int) reg))
2014 => [Ra + Rb << sv] */
2015 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2016 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2017 return true;
2018 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2019 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2020 return true;
2021 else
2022 return false;
2023
2024 case LO_SUM:
2025 if (!TARGET_GP_DIRECT)
2026 return true;
2027
2028 default:
2029 return false;
2030 }
2031 }
2032
2033 \f
2034 /* Describing Relative Costs of Operations. */
2035
2036 static int
2037 nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2038 reg_class_t from,
2039 reg_class_t to)
2040 {
2041 if (from == HIGH_REGS || to == HIGH_REGS)
2042 return 6;
2043
2044 return 2;
2045 }
2046
2047 static int
2048 nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
2049 reg_class_t rclass ATTRIBUTE_UNUSED,
2050 bool in ATTRIBUTE_UNUSED)
2051 {
2052 return 8;
2053 }
2054
2055 /* This target hook describes the relative costs of RTL expressions.
2056 Return 'true' when all subexpressions of x have been processed.
2057 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2058 Refer to gcc/rtlanal.c for more information. */
2059 static bool
2060 nds32_rtx_costs (rtx x,
2061 int code,
2062 int outer_code,
2063 int opno,
2064 int *total,
2065 bool speed)
2066 {
2067 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
2068 }
2069
2070 static int
2071 nds32_address_cost (rtx address,
2072 enum machine_mode mode,
2073 addr_space_t as,
2074 bool speed)
2075 {
2076 return nds32_address_cost_impl (address, mode, as, speed);
2077 }
2078
2079 \f
2080 /* Defining the Output Assembler Language. */
2081
2082 /* -- The Overall Framework of an Assembler File. */
2083
2084 static void
2085 nds32_asm_file_start (void)
2086 {
2087 default_file_start ();
2088
2089 /* Tell assembler which ABI we are using. */
2090 fprintf (asm_out_file, "\t! ABI version\n");
2091 fprintf (asm_out_file, "\t.abi_2\n");
2092
2093 /* Tell assembler that this asm code is generated by compiler. */
2094 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2095 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2096 /* Give assembler the size of each vector for interrupt handler. */
2097 fprintf (asm_out_file, "\t! This vector size directive is required "
2098 "for checking inconsistency on interrupt handler\n");
2099 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2100
2101 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2102 the compiler may produce 'la $fp,_FP_BASE_' instruction
2103 at prologue for fp-as-gp optimization.
2104 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2105 in case user does not pass '--relax' option to linker. */
2106 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2107 {
2108 fprintf (asm_out_file, "\t! This weak reference is required to do "
2109 "fp-as-gp link time optimization\n");
2110 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2111 }
2112 /* If user enables '-mex9', we should emit relaxation directive
2113 to tell linker that this file is allowed to do ex9 optimization. */
2114 if (TARGET_EX9)
2115 {
2116 fprintf (asm_out_file, "\t! This relaxation directive is required "
2117 "to do ex9 link time optimization\n");
2118 fprintf (asm_out_file, "\t.relax\tex9\n");
2119 }
2120
2121 fprintf (asm_out_file, "\t! ------------------------------------\n");
2122
2123 if (TARGET_ISA_V2)
2124 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2125 if (TARGET_ISA_V3)
2126 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2127 if (TARGET_ISA_V3M)
2128 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2129
2130 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2131 ((TARGET_BIG_ENDIAN) ? "big-endian"
2132 : "little-endian"));
2133
2134 fprintf (asm_out_file, "\t! ------------------------------------\n");
2135
2136 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2137 ((TARGET_CMOV) ? "Yes"
2138 : "No"));
2139 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2140 ((TARGET_PERF_EXT) ? "Yes"
2141 : "No"));
2142
2143 fprintf (asm_out_file, "\t! ------------------------------------\n");
2144
2145 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2146 ((TARGET_V3PUSH) ? "Yes"
2147 : "No"));
2148 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2149 ((TARGET_16_BIT) ? "Yes"
2150 : "No"));
2151 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2152 ((TARGET_GP_DIRECT) ? "Yes"
2153 : "No"));
2154 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2155 ((TARGET_REDUCED_REGS) ? "Yes"
2156 : "No"));
2157
2158 fprintf (asm_out_file, "\t! ------------------------------------\n");
2159
2160 if (optimize_size)
2161 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2162 else
2163 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2164
2165 fprintf (asm_out_file, "\t! ------------------------------------\n");
2166
2167 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2168 nds32_cache_block_size);
2169
2170 fprintf (asm_out_file, "\t! ------------------------------------\n");
2171
2172 nds32_asm_file_start_for_isr ();
2173 }
2174
2175 static void
2176 nds32_asm_file_end (void)
2177 {
2178 nds32_asm_file_end_for_isr ();
2179
2180 fprintf (asm_out_file, "\t! ------------------------------------\n");
2181 }
2182
2183 /* -- Output and Generation of Labels. */
2184
2185 static void
2186 nds32_asm_globalize_label (FILE *stream, const char *name)
2187 {
2188 fputs ("\t.global\t", stream);
2189 assemble_name (stream, name);
2190 fputs ("\n", stream);
2191 }
2192
2193 /* -- Output of Assembler Instructions. */
2194
2195 static void
2196 nds32_print_operand (FILE *stream, rtx x, int code)
2197 {
2198 int op_value;
2199
2200 switch (code)
2201 {
2202 case 0 :
2203 /* Do nothing special. */
2204 break;
2205
2206 case 'V':
2207 /* 'x' is supposed to be CONST_INT, get the value. */
2208 gcc_assert (CONST_INT_P (x));
2209 op_value = INTVAL (x);
2210
2211 /* According to the Andes architecture,
2212 the system/user register index range is 0 ~ 1023.
2213 In order to avoid conflict between user-specified-integer value
2214 and enum-specified-register value,
2215 the 'enum nds32_intrinsic_registers' value
2216 in nds32_intrinsic.h starts from 1024. */
2217 if (op_value < 1024 && op_value >= 0)
2218 {
2219 /* If user gives integer value directly (0~1023),
2220 we just print out the value. */
2221 fprintf (stream, "%d", op_value);
2222 }
2223 else if (op_value < 0
2224 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2225 + 1024))
2226 {
2227 /* The enum index value for array size is out of range. */
2228 error ("intrinsic register index is out of range");
2229 }
2230 else
2231 {
2232 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2233 we can print out register name. Remember to substract 1024. */
2234 fprintf (stream, "%s",
2235 nds32_intrinsic_register_names[op_value - 1024]);
2236 }
2237
2238 /* No need to handle following process, so return immediately. */
2239 return;
2240
2241 default :
2242 /* Unknown flag. */
2243 output_operand_lossage ("invalid operand output code");
2244 break;
2245 }
2246
2247 switch (GET_CODE (x))
2248 {
2249 case LABEL_REF:
2250 case SYMBOL_REF:
2251 output_addr_const (stream, x);
2252 break;
2253
2254 case REG:
2255 /* Forbid using static chain register ($r16)
2256 on reduced-set registers configuration. */
2257 if (TARGET_REDUCED_REGS
2258 && REGNO (x) == STATIC_CHAIN_REGNUM)
2259 sorry ("a nested function is not supported for reduced registers");
2260
2261 /* Normal cases, print out register name. */
2262 fputs (reg_names[REGNO (x)], stream);
2263 break;
2264
2265 case MEM:
2266 output_address (XEXP (x, 0));
2267 break;
2268
2269 case CODE_LABEL:
2270 case CONST_INT:
2271 case CONST:
2272 output_addr_const (stream, x);
2273 break;
2274
2275 default:
2276 /* Generally, output_addr_const () is able to handle most cases.
2277 We want to see what CODE could appear,
2278 so we use gcc_unreachable() to stop it. */
2279 debug_rtx (x);
2280 gcc_unreachable ();
2281 break;
2282 }
2283 }
2284
2285 static void
2286 nds32_print_operand_address (FILE *stream, rtx x)
2287 {
2288 rtx op0, op1;
2289
2290 switch (GET_CODE (x))
2291 {
2292 case SYMBOL_REF:
2293 case CONST:
2294 /* [ + symbol_ref] */
2295 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2296 fputs ("[ + ", stream);
2297 output_addr_const (stream, x);
2298 fputs ("]", stream);
2299 break;
2300
2301 case REG:
2302 /* Forbid using static chain register ($r16)
2303 on reduced-set registers configuration. */
2304 if (TARGET_REDUCED_REGS
2305 && REGNO (x) == STATIC_CHAIN_REGNUM)
2306 sorry ("a nested function is not supported for reduced registers");
2307
2308 /* [Ra] */
2309 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2310 break;
2311
2312 case PLUS:
2313 op0 = XEXP (x, 0);
2314 op1 = XEXP (x, 1);
2315
2316 /* Checking op0, forbid using static chain register ($r16)
2317 on reduced-set registers configuration. */
2318 if (TARGET_REDUCED_REGS
2319 && REG_P (op0)
2320 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2321 sorry ("a nested function is not supported for reduced registers");
2322 /* Checking op1, forbid using static chain register ($r16)
2323 on reduced-set registers configuration. */
2324 if (TARGET_REDUCED_REGS
2325 && REG_P (op1)
2326 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2327 sorry ("a nested function is not supported for reduced registers");
2328
2329 if (REG_P (op0) && CONST_INT_P (op1))
2330 {
2331 /* [Ra + imm] */
2332 fprintf (stream, "[%s + (%d)]",
2333 reg_names[REGNO (op0)], (int)INTVAL (op1));
2334 }
2335 else if (REG_P (op0) && REG_P (op1))
2336 {
2337 /* [Ra + Rb] */
2338 fprintf (stream, "[%s + %s]",
2339 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2340 }
2341 else if (GET_CODE (op0) == MULT && REG_P (op1))
2342 {
2343 /* [Ra + Rb << sv]
2344 From observation, the pattern looks like:
2345 (plus:SI (mult:SI (reg:SI 58)
2346 (const_int 4 [0x4]))
2347 (reg/f:SI 57)) */
2348 int sv;
2349
2350 /* We need to set sv to output shift value. */
2351 if (INTVAL (XEXP (op0, 1)) == 1)
2352 sv = 0;
2353 else if (INTVAL (XEXP (op0, 1)) == 2)
2354 sv = 1;
2355 else if (INTVAL (XEXP (op0, 1)) == 4)
2356 sv = 2;
2357 else
2358 gcc_unreachable ();
2359
2360 fprintf (stream, "[%s + %s << %d]",
2361 reg_names[REGNO (op1)],
2362 reg_names[REGNO (XEXP (op0, 0))],
2363 sv);
2364 }
2365 else
2366 {
2367 /* The control flow is not supposed to be here. */
2368 debug_rtx (x);
2369 gcc_unreachable ();
2370 }
2371
2372 break;
2373
2374 case POST_MODIFY:
2375 /* (post_modify (regA) (plus (regA) (regB)))
2376 (post_modify (regA) (plus (regA) (const_int)))
2377 We would like to extract
2378 regA and regB (or const_int) from plus rtx. */
2379 op0 = XEXP (XEXP (x, 1), 0);
2380 op1 = XEXP (XEXP (x, 1), 1);
2381
2382 /* Checking op0, forbid using static chain register ($r16)
2383 on reduced-set registers configuration. */
2384 if (TARGET_REDUCED_REGS
2385 && REG_P (op0)
2386 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2387 sorry ("a nested function is not supported for reduced registers");
2388 /* Checking op1, forbid using static chain register ($r16)
2389 on reduced-set registers configuration. */
2390 if (TARGET_REDUCED_REGS
2391 && REG_P (op1)
2392 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2393 sorry ("a nested function is not supported for reduced registers");
2394
2395 if (REG_P (op0) && REG_P (op1))
2396 {
2397 /* [Ra], Rb */
2398 fprintf (stream, "[%s], %s",
2399 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2400 }
2401 else if (REG_P (op0) && CONST_INT_P (op1))
2402 {
2403 /* [Ra], imm */
2404 fprintf (stream, "[%s], %d",
2405 reg_names[REGNO (op0)], (int)INTVAL (op1));
2406 }
2407 else
2408 {
2409 /* The control flow is not supposed to be here. */
2410 debug_rtx (x);
2411 gcc_unreachable ();
2412 }
2413
2414 break;
2415
2416 case POST_INC:
2417 case POST_DEC:
2418 op0 = XEXP (x, 0);
2419
2420 /* Checking op0, forbid using static chain register ($r16)
2421 on reduced-set registers configuration. */
2422 if (TARGET_REDUCED_REGS
2423 && REG_P (op0)
2424 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2425 sorry ("a nested function is not supported for reduced registers");
2426
2427 if (REG_P (op0))
2428 {
2429 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2430 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2431 We only need to deal with register Ra. */
2432 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2433 }
2434 else
2435 {
2436 /* The control flow is not supposed to be here. */
2437 debug_rtx (x);
2438 gcc_unreachable ();
2439 }
2440
2441 break;
2442
2443 default :
2444 /* Generally, output_addr_const () is able to handle most cases.
2445 We want to see what CODE could appear,
2446 so we use gcc_unreachable() to stop it. */
2447 debug_rtx (x);
2448 gcc_unreachable ();
2449 break;
2450 }
2451 }
2452
2453 \f
2454 /* Defining target-specific uses of __attribute__. */
2455
2456 /* Add some checking after merging attributes. */
2457 static tree
2458 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2459 {
2460 tree combined_attrs;
2461
2462 /* Create combined attributes. */
2463 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2464 DECL_ATTRIBUTES (newdecl));
2465
2466 /* Since newdecl is acutally a duplicate of olddecl,
2467 we can take olddecl for some operations. */
2468 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2469 {
2470 /* Check isr-specific attributes conflict. */
2471 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2472 }
2473
2474 return combined_attrs;
2475 }
2476
2477 /* Add some checking when inserting attributes. */
2478 static void
2479 nds32_insert_attributes (tree decl, tree *attributes)
2480 {
2481 /* For function declaration, we need to check isr-specific attributes:
2482 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2483 2. Check valid integer value for interrupt/exception.
2484 3. Check valid integer value for reset.
2485 4. Check valid function for nmi/warm. */
2486 if (TREE_CODE (decl) == FUNCTION_DECL)
2487 {
2488 tree func_attrs;
2489 tree intr, excp, reset;
2490
2491 /* Pick up function attributes. */
2492 func_attrs = *attributes;
2493
2494 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2495 nds32_check_isr_attrs_conflict (decl, func_attrs);
2496
2497 /* Now we are starting to check valid id value
2498 for interrupt/exception/reset.
2499 Note that we ONLY check its validity here.
2500 To construct isr vector information, it is still performed
2501 by nds32_construct_isr_vectors_information(). */
2502 intr = lookup_attribute ("interrupt", func_attrs);
2503 excp = lookup_attribute ("exception", func_attrs);
2504 reset = lookup_attribute ("reset", func_attrs);
2505
2506 if (intr || excp)
2507 {
2508 /* Deal with interrupt/exception. */
2509 tree id_list;
2510 unsigned int lower_bound, upper_bound;
2511
2512 /* The way to handle interrupt or exception is the same,
2513 we just need to take care of actual vector number.
2514 For interrupt(0..63), the actual vector number is (9..72).
2515 For exception(1..8), the actual vector number is (1..8). */
2516 lower_bound = (intr) ? (0) : (1);
2517 upper_bound = (intr) ? (63) : (8);
2518
2519 /* Prepare id list so that we can traverse id value. */
2520 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2521
2522 /* 2. Check valid integer value for interrupt/exception. */
2523 while (id_list)
2524 {
2525 tree id;
2526
2527 /* Pick up each vector id value. */
2528 id = TREE_VALUE (id_list);
2529 /* Issue error if it is not a valid integer value. */
2530 if (TREE_CODE (id) != INTEGER_CST
2531 || wi::ltu_p (id, lower_bound)
2532 || wi::gtu_p (id, upper_bound))
2533 error ("invalid id value for interrupt/exception attribute");
2534
2535 /* Advance to next id. */
2536 id_list = TREE_CHAIN (id_list);
2537 }
2538 }
2539 else if (reset)
2540 {
2541 /* Deal with reset. */
2542 tree id_list;
2543 tree id;
2544 tree nmi, warm;
2545 unsigned int lower_bound;
2546 unsigned int upper_bound;
2547
2548 /* Prepare id_list and identify id value so that
2549 we can check if total number of vectors is valid. */
2550 id_list = TREE_VALUE (reset);
2551 id = TREE_VALUE (id_list);
2552
2553 /* The maximum numbers for user's interrupt is 64. */
2554 lower_bound = 0;
2555 upper_bound = 64;
2556
2557 /* 3. Check valid integer value for reset. */
2558 if (TREE_CODE (id) != INTEGER_CST
2559 || wi::ltu_p (id, lower_bound)
2560 || wi::gtu_p (id, upper_bound))
2561 error ("invalid id value for reset attribute");
2562
2563 /* 4. Check valid function for nmi/warm. */
2564 nmi = lookup_attribute ("nmi", func_attrs);
2565 warm = lookup_attribute ("warm", func_attrs);
2566
2567 if (nmi != NULL_TREE)
2568 {
2569 tree nmi_func_list;
2570 tree nmi_func;
2571
2572 nmi_func_list = TREE_VALUE (nmi);
2573 nmi_func = TREE_VALUE (nmi_func_list);
2574
2575 /* Issue error if it is not a valid nmi function. */
2576 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2577 error ("invalid nmi function for reset attribute");
2578 }
2579
2580 if (warm != NULL_TREE)
2581 {
2582 tree warm_func_list;
2583 tree warm_func;
2584
2585 warm_func_list = TREE_VALUE (warm);
2586 warm_func = TREE_VALUE (warm_func_list);
2587
2588 /* Issue error if it is not a valid warm function. */
2589 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2590 error ("invalid warm function for reset attribute");
2591 }
2592 }
2593 else
2594 {
2595 /* No interrupt, exception, or reset attribute is set. */
2596 return;
2597 }
2598 }
2599 }
2600
2601 static bool
2602 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2603 tree pop_target ATTRIBUTE_UNUSED)
2604 {
2605 /* Currently, we do not parse any pragma target by ourself,
2606 so just simply return false. */
2607 return false;
2608 }
2609
2610 static void
2611 nds32_option_override (void)
2612 {
2613 /* After all the command options have been parsed,
2614 we shall deal with some flags for changing compiler settings. */
2615
2616 /* At first, we check if we have to strictly
2617 set some flags based on ISA family. */
2618 if (TARGET_ISA_V2)
2619 {
2620 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2621 target_flags &= ~MASK_V3PUSH;
2622 }
2623 if (TARGET_ISA_V3)
2624 {
2625 /* Under V3 ISA, currently nothing should be strictly set. */
2626 }
2627 if (TARGET_ISA_V3M)
2628 {
2629 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2630 target_flags |= MASK_REDUCED_REGS;
2631 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2632 target_flags &= ~MASK_PERF_EXT;
2633 }
2634
2635 /* See if we are using reduced-set registers:
2636 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2637 If so, we must forbid using $r11~$r14, $r16~$r27. */
2638 if (TARGET_REDUCED_REGS)
2639 {
2640 int r;
2641
2642 /* Prevent register allocator from
2643 choosing it as doing register allocation. */
2644 for (r = 11; r <= 14; r++)
2645 fixed_regs[r] = call_used_regs[r] = 1;
2646 for (r = 16; r <= 27; r++)
2647 fixed_regs[r] = call_used_regs[r] = 1;
2648 }
2649
2650 /* See if user explicitly would like to use fp-as-gp optimization.
2651 If so, we must prevent $fp from being allocated
2652 during register allocation. */
2653 if (TARGET_FORCE_FP_AS_GP)
2654 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2655
2656 if (!TARGET_16_BIT)
2657 {
2658 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2659 target_flags &= ~MASK_V3PUSH;
2660 }
2661
2662 /* Currently, we don't support PIC code generation yet. */
2663 if (flag_pic)
2664 sorry ("not support -fpic");
2665 }
2666
2667 \f
2668 /* Miscellaneous Parameters. */
2669
2670 static void
2671 nds32_init_builtins (void)
2672 {
2673 nds32_init_builtins_impl ();
2674 }
2675
2676 static rtx
2677 nds32_expand_builtin (tree exp,
2678 rtx target,
2679 rtx subtarget,
2680 enum machine_mode mode,
2681 int ignore)
2682 {
2683 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2684 }
2685
2686
2687 /* ------------------------------------------------------------------------ */
2688
2689 /* PART 4: Implemet extern function definitions,
2690 the prototype is in nds32-protos.h. */
2691 \f
2692 /* Defining Data Structures for Per-function Information. */
2693
2694 void
2695 nds32_init_expanders (void)
2696 {
2697 /* Arrange to initialize and mark the machine per-function status. */
2698 init_machine_status = nds32_init_machine_status;
2699 }
2700
2701 \f
2702 /* Register Usage. */
2703
2704 /* -- How Values Fit in Registers. */
2705
2706 int
2707 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2708 enum machine_mode mode)
2709 {
2710 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2711 }
2712
2713 int
2714 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
2715 {
2716 /* Restrict double-word quantities to even register pairs. */
2717 if (HARD_REGNO_NREGS (regno, mode) == 1
2718 || !((regno) & 1))
2719 return 1;
2720
2721 return 0;
2722 }
2723
2724 \f
2725 /* Register Classes. */
2726
2727 enum reg_class
2728 nds32_regno_reg_class (int regno)
2729 {
2730 /* Refer to nds32.h for more register class details. */
2731
2732 if (regno >= 0 && regno <= 7)
2733 return LOW_REGS;
2734 else if (regno >= 8 && regno <= 11)
2735 return MIDDLE_REGS;
2736 else if (regno >= 12 && regno <= 14)
2737 return HIGH_REGS;
2738 else if (regno == 15)
2739 return R15_TA_REG;
2740 else if (regno >= 16 && regno <= 19)
2741 return MIDDLE_REGS;
2742 else if (regno >= 20 && regno <= 31)
2743 return HIGH_REGS;
2744 else if (regno == 32 || regno == 33)
2745 return FRAME_REGS;
2746 else
2747 return NO_REGS;
2748 }
2749
2750 \f
2751 /* Stack Layout and Calling Conventions. */
2752
2753 /* -- Basic Stack Layout. */
2754
2755 rtx
2756 nds32_return_addr_rtx (int count,
2757 rtx frameaddr ATTRIBUTE_UNUSED)
2758 {
2759 /* There is no way to determine the return address
2760 if frameaddr is the frame that has 'count' steps
2761 up from current frame. */
2762 if (count != 0)
2763 return NULL_RTX;
2764
2765 /* If count == 0, it means we are at current frame,
2766 the return address is $r30 ($lp). */
2767 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2768 }
2769
2770 /* -- Eliminating Frame Pointer and Arg Pointer. */
2771
2772 HOST_WIDE_INT
2773 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2774 {
2775 HOST_WIDE_INT offset;
2776
2777 /* Compute and setup stack frame size.
2778 The result will be in cfun->machine. */
2779 nds32_compute_stack_frame ();
2780
2781 /* Remember to consider
2782 cfun->machine->callee_saved_area_padding_bytes
2783 when calculating offset. */
2784 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2785 {
2786 offset = (cfun->machine->fp_size
2787 + cfun->machine->gp_size
2788 + cfun->machine->lp_size
2789 + cfun->machine->callee_saved_regs_size
2790 + cfun->machine->callee_saved_area_padding_bytes
2791 + cfun->machine->local_size
2792 + cfun->machine->out_args_size);
2793 }
2794 else if (from_reg == ARG_POINTER_REGNUM
2795 && to_reg == HARD_FRAME_POINTER_REGNUM)
2796 {
2797 offset = 0;
2798 }
2799 else if (from_reg == FRAME_POINTER_REGNUM
2800 && to_reg == STACK_POINTER_REGNUM)
2801 {
2802 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2803 }
2804 else if (from_reg == FRAME_POINTER_REGNUM
2805 && to_reg == HARD_FRAME_POINTER_REGNUM)
2806 {
2807 offset = (-1) * (cfun->machine->fp_size
2808 + cfun->machine->gp_size
2809 + cfun->machine->lp_size
2810 + cfun->machine->callee_saved_regs_size
2811 + cfun->machine->callee_saved_area_padding_bytes);
2812 }
2813 else
2814 {
2815 gcc_unreachable ();
2816 }
2817
2818 return offset;
2819 }
2820
2821 /* -- Passing Arguments in Registers. */
2822
2823 void
2824 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2825 tree fntype ATTRIBUTE_UNUSED,
2826 rtx libname ATTRIBUTE_UNUSED,
2827 tree fndecl ATTRIBUTE_UNUSED,
2828 int n_named_args ATTRIBUTE_UNUSED)
2829 {
2830 /* Initial available registers
2831 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2832 for passing arguments. */
2833 cum->gpr_offset = 0;
2834 }
2835
2836 /* -- Function Entry and Exit. */
2837
2838 /* Function for normal multiple push prologue. */
2839 void
2840 nds32_expand_prologue (void)
2841 {
2842 int fp_adjust;
2843 int sp_adjust;
2844 int en4_const;
2845
2846 rtx Rb, Re;
2847 rtx fp_adjust_insn, sp_adjust_insn;
2848
2849 /* Compute and setup stack frame size.
2850 The result will be in cfun->machine. */
2851 nds32_compute_stack_frame ();
2852
2853 /* If this is a variadic function, first we need to push argument
2854 registers that hold the unnamed argument value. */
2855 if (cfun->machine->va_args_size != 0)
2856 {
2857 Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
2858 Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
2859 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2860 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0));
2861
2862 /* We may also need to adjust stack pointer for padding bytes
2863 because varargs may cause $sp not 8-byte aligned. */
2864 if (cfun->machine->va_args_area_padding_bytes)
2865 {
2866 /* Generate sp adjustment instruction. */
2867 sp_adjust = cfun->machine->va_args_area_padding_bytes;
2868 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2869 stack_pointer_rtx,
2870 GEN_INT (-1 * sp_adjust));
2871
2872 /* Emit rtx into instructions list and receive INSN rtx form. */
2873 sp_adjust_insn = emit_insn (sp_adjust_insn);
2874
2875 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2876 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2877 generate CFI (Call Frame Information) stuff. */
2878 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2879 }
2880 }
2881
2882 /* If the function is 'naked',
2883 we do not have to generate prologue code fragment. */
2884 if (cfun->machine->naked_p)
2885 return;
2886
2887 /* Get callee_first_regno and callee_last_regno. */
2888 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2889 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2890
2891 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2892 the pattern 'stack_push_multiple' is implemented in nds32.md.
2893 For En4 field, we have to calculate its constant value.
2894 Refer to Andes ISA for more information. */
2895 en4_const = 0;
2896 if (cfun->machine->fp_size)
2897 en4_const += 8;
2898 if (cfun->machine->gp_size)
2899 en4_const += 4;
2900 if (cfun->machine->lp_size)
2901 en4_const += 2;
2902
2903 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2904 to be saved, we don't have to create multiple push instruction.
2905 Otherwise, a multiple push instruction is needed. */
2906 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2907 {
2908 /* Create multiple push instruction rtx. */
2909 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
2910 }
2911
2912 /* Check frame_pointer_needed to see
2913 if we shall emit fp adjustment instruction. */
2914 if (frame_pointer_needed)
2915 {
2916 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2917 + (4 * callee-saved-registers)
2918 Note: No need to adjust
2919 cfun->machine->callee_saved_area_padding_bytes,
2920 because, at this point, stack pointer is just
2921 at the position after push instruction. */
2922 fp_adjust = cfun->machine->fp_size
2923 + cfun->machine->gp_size
2924 + cfun->machine->lp_size
2925 + cfun->machine->callee_saved_regs_size;
2926 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2927 stack_pointer_rtx,
2928 GEN_INT (fp_adjust));
2929 /* Emit rtx into instructions list and receive INSN rtx form. */
2930 fp_adjust_insn = emit_insn (fp_adjust_insn);
2931 }
2932
2933 /* Adjust $sp = $sp - local_size - out_args_size
2934 - callee_saved_area_padding_bytes. */
2935 sp_adjust = cfun->machine->local_size
2936 + cfun->machine->out_args_size
2937 + cfun->machine->callee_saved_area_padding_bytes;
2938 /* sp_adjust value may be out of range of the addi instruction,
2939 create alternative add behavior with TA_REGNUM if necessary,
2940 using NEGATIVE value to tell that we are decreasing address. */
2941 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2942 if (sp_adjust)
2943 {
2944 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2945 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2946 stack_pointer_rtx,
2947 GEN_INT (-1 * sp_adjust));
2948 /* Emit rtx into instructions list and receive INSN rtx form. */
2949 sp_adjust_insn = emit_insn (sp_adjust_insn);
2950
2951 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2952 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2953 generate CFI (Call Frame Information) stuff. */
2954 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2955 }
2956
2957 /* Prevent the instruction scheduler from
2958 moving instructions across the boundary. */
2959 emit_insn (gen_blockage ());
2960 }
2961
2962 /* Function for normal multiple pop epilogue. */
2963 void
2964 nds32_expand_epilogue (void)
2965 {
2966 int sp_adjust;
2967 int en4_const;
2968
2969 rtx Rb, Re;
2970 rtx sp_adjust_insn;
2971
2972 /* Compute and setup stack frame size.
2973 The result will be in cfun->machine. */
2974 nds32_compute_stack_frame ();
2975
2976 /* Prevent the instruction scheduler from
2977 moving instructions across the boundary. */
2978 emit_insn (gen_blockage ());
2979
2980 /* If the function is 'naked', we do not have to generate
2981 epilogue code fragment BUT 'ret' instruction.
2982 However, if this function is also a variadic function,
2983 we need to create adjust stack pointer before 'ret' instruction. */
2984 if (cfun->machine->naked_p)
2985 {
2986 /* If this is a variadic function, we do not have to restore argument
2987 registers but need to adjust stack pointer back to previous stack
2988 frame location before return. */
2989 if (cfun->machine->va_args_size != 0)
2990 {
2991 /* Generate sp adjustment instruction.
2992 We need to consider padding bytes here. */
2993 sp_adjust = cfun->machine->va_args_size
2994 + cfun->machine->va_args_area_padding_bytes;
2995 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2996 stack_pointer_rtx,
2997 GEN_INT (sp_adjust));
2998 /* Emit rtx into instructions list and receive INSN rtx form. */
2999 sp_adjust_insn = emit_insn (sp_adjust_insn);
3000
3001 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3002 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3003 generate CFI (Call Frame Information) stuff. */
3004 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3005 }
3006
3007 /* Generate return instruction by using
3008 unspec_volatile_func_return pattern.
3009 Make sure this instruction is after gen_blockage().
3010 NOTE that $lp will become 'live'
3011 after this instruction has been emitted. */
3012 emit_insn (gen_unspec_volatile_func_return ());
3013 return;
3014 }
3015
3016 if (frame_pointer_needed)
3017 {
3018 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3019 - (4 * callee-saved-registers)
3020 Note: No need to adjust
3021 cfun->machine->callee_saved_area_padding_bytes,
3022 because we want to adjust stack pointer
3023 to the position for pop instruction. */
3024 sp_adjust = cfun->machine->fp_size
3025 + cfun->machine->gp_size
3026 + cfun->machine->lp_size
3027 + cfun->machine->callee_saved_regs_size;
3028 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3029 hard_frame_pointer_rtx,
3030 GEN_INT (-1 * sp_adjust));
3031 /* Emit rtx into instructions list and receive INSN rtx form. */
3032 sp_adjust_insn = emit_insn (sp_adjust_insn);
3033
3034 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3035 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3036 }
3037 else
3038 {
3039 /* If frame pointer is NOT needed,
3040 we cannot calculate the sp adjustment from frame pointer.
3041 Instead, we calculate the adjustment by local_size,
3042 out_args_size, and callee_saved_area_padding_bytes.
3043 Notice that such sp adjustment value may be out of range,
3044 so we have to deal with it as well. */
3045
3046 /* Adjust $sp = $sp + local_size + out_args_size
3047 + callee_saved_area_padding_bytes. */
3048 sp_adjust = cfun->machine->local_size
3049 + cfun->machine->out_args_size
3050 + cfun->machine->callee_saved_area_padding_bytes;
3051 /* sp_adjust value may be out of range of the addi instruction,
3052 create alternative add behavior with TA_REGNUM if necessary,
3053 using POSITIVE value to tell that we are increasing address. */
3054 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3055 if (sp_adjust)
3056 {
3057 /* Generate sp adjustment instruction
3058 if and only if sp_adjust != 0. */
3059 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3060 stack_pointer_rtx,
3061 GEN_INT (sp_adjust));
3062 /* Emit rtx into instructions list and receive INSN rtx form. */
3063 sp_adjust_insn = emit_insn (sp_adjust_insn);
3064
3065 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3066 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3067 }
3068 }
3069
3070 /* Get callee_first_regno and callee_last_regno. */
3071 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3072 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3073
3074 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3075 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3076 For En4 field, we have to calculate its constant value.
3077 Refer to Andes ISA for more information. */
3078 en4_const = 0;
3079 if (cfun->machine->fp_size)
3080 en4_const += 8;
3081 if (cfun->machine->gp_size)
3082 en4_const += 4;
3083 if (cfun->machine->lp_size)
3084 en4_const += 2;
3085
3086 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3087 to be saved, we don't have to create multiple pop instruction.
3088 Otherwise, a multiple pop instruction is needed. */
3089 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3090 {
3091 /* Create multiple pop instruction rtx. */
3092 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3093 }
3094
3095 /* If this is a variadic function, we do not have to restore argument
3096 registers but need to adjust stack pointer back to previous stack
3097 frame location before return. */
3098 if (cfun->machine->va_args_size != 0)
3099 {
3100 /* Generate sp adjustment instruction.
3101 We need to consider padding bytes here. */
3102 sp_adjust = cfun->machine->va_args_size
3103 + cfun->machine->va_args_area_padding_bytes;
3104 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3105 stack_pointer_rtx,
3106 GEN_INT (sp_adjust));
3107 /* Emit rtx into instructions list and receive INSN rtx form. */
3108 sp_adjust_insn = emit_insn (sp_adjust_insn);
3109
3110 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3111 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3112 generate CFI (Call Frame Information) stuff. */
3113 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3114 }
3115
3116 /* Generate return instruction by using
3117 unspec_volatile_func_return pattern. */
3118 emit_insn (gen_unspec_volatile_func_return ());
3119 }
3120
3121 /* Function for v3push prologue. */
3122 void
3123 nds32_expand_prologue_v3push (void)
3124 {
3125 int fp_adjust;
3126 int sp_adjust;
3127
3128 rtx Rb, Re;
3129 rtx fp_adjust_insn, sp_adjust_insn;
3130
3131 /* Compute and setup stack frame size.
3132 The result will be in cfun->machine. */
3133 nds32_compute_stack_frame ();
3134
3135 /* If the function is 'naked',
3136 we do not have to generate prologue code fragment. */
3137 if (cfun->machine->naked_p)
3138 return;
3139
3140 /* Get callee_first_regno and callee_last_regno. */
3141 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3142 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3143
3144 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3145 where imm8u has to be 8-byte alignment. */
3146 sp_adjust = cfun->machine->local_size
3147 + cfun->machine->out_args_size
3148 + cfun->machine->callee_saved_area_padding_bytes;
3149
3150 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3151 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3152 {
3153 /* We can use 'push25 Re,imm8u'. */
3154
3155 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3156 the pattern 'stack_v3push' is implemented in nds32.md.
3157 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3158 nds32_emit_stack_v3push (Rb, Re,
3159 GEN_INT (14), GEN_INT (sp_adjust));
3160
3161 /* Check frame_pointer_needed to see
3162 if we shall emit fp adjustment instruction. */
3163 if (frame_pointer_needed)
3164 {
3165 /* adjust $fp = $sp + 4 ($fp size)
3166 + 4 ($gp size)
3167 + 4 ($lp size)
3168 + (4 * n) (callee-saved registers)
3169 + sp_adjust ('push25 Re,imm8u')
3170 Note: Since we use 'push25 Re,imm8u',
3171 the position of stack pointer is further
3172 changed after push instruction.
3173 Hence, we need to take sp_adjust value
3174 into consideration. */
3175 fp_adjust = cfun->machine->fp_size
3176 + cfun->machine->gp_size
3177 + cfun->machine->lp_size
3178 + cfun->machine->callee_saved_regs_size
3179 + sp_adjust;
3180 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3181 stack_pointer_rtx,
3182 GEN_INT (fp_adjust));
3183 /* Emit rtx into instructions list and receive INSN rtx form. */
3184 fp_adjust_insn = emit_insn (fp_adjust_insn);
3185 }
3186 }
3187 else
3188 {
3189 /* We have to use 'push25 Re,0' and
3190 expand one more instruction to adjust $sp later. */
3191
3192 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3193 the pattern 'stack_v3push' is implemented in nds32.md.
3194 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3195 nds32_emit_stack_v3push (Rb, Re,
3196 GEN_INT (14), GEN_INT (0));
3197
3198 /* Check frame_pointer_needed to see
3199 if we shall emit fp adjustment instruction. */
3200 if (frame_pointer_needed)
3201 {
3202 /* adjust $fp = $sp + 4 ($fp size)
3203 + 4 ($gp size)
3204 + 4 ($lp size)
3205 + (4 * n) (callee-saved registers)
3206 Note: Since we use 'push25 Re,0',
3207 the stack pointer is just at the position
3208 after push instruction.
3209 No need to take sp_adjust into consideration. */
3210 fp_adjust = cfun->machine->fp_size
3211 + cfun->machine->gp_size
3212 + cfun->machine->lp_size
3213 + cfun->machine->callee_saved_regs_size;
3214 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3215 stack_pointer_rtx,
3216 GEN_INT (fp_adjust));
3217 /* Emit rtx into instructions list and receive INSN rtx form. */
3218 fp_adjust_insn = emit_insn (fp_adjust_insn);
3219 }
3220
3221 /* Because we use 'push25 Re,0',
3222 we need to expand one more instruction to adjust $sp.
3223 However, sp_adjust value may be out of range of the addi instruction,
3224 create alternative add behavior with TA_REGNUM if necessary,
3225 using NEGATIVE value to tell that we are decreasing address. */
3226 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3227 if (sp_adjust)
3228 {
3229 /* Generate sp adjustment instruction
3230 if and only if sp_adjust != 0. */
3231 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3232 stack_pointer_rtx,
3233 GEN_INT (-1 * sp_adjust));
3234 /* Emit rtx into instructions list and receive INSN rtx form. */
3235 sp_adjust_insn = emit_insn (sp_adjust_insn);
3236
3237 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3238 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3239 generate CFI (Call Frame Information) stuff. */
3240 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3241 }
3242 }
3243
3244 /* Prevent the instruction scheduler from
3245 moving instructions across the boundary. */
3246 emit_insn (gen_blockage ());
3247 }
3248
3249 /* Function for v3pop epilogue. */
3250 void
3251 nds32_expand_epilogue_v3pop (void)
3252 {
3253 int sp_adjust;
3254
3255 rtx Rb, Re;
3256 rtx sp_adjust_insn;
3257
3258 /* Compute and setup stack frame size.
3259 The result will be in cfun->machine. */
3260 nds32_compute_stack_frame ();
3261
3262 /* Prevent the instruction scheduler from
3263 moving instructions across the boundary. */
3264 emit_insn (gen_blockage ());
3265
3266 /* If the function is 'naked', we do not have to generate
3267 epilogue code fragment BUT 'ret' instruction. */
3268 if (cfun->machine->naked_p)
3269 {
3270 /* Generate return instruction by using
3271 unspec_volatile_func_return pattern.
3272 Make sure this instruction is after gen_blockage().
3273 NOTE that $lp will become 'live'
3274 after this instruction has been emitted. */
3275 emit_insn (gen_unspec_volatile_func_return ());
3276 return;
3277 }
3278
3279 /* Get callee_first_regno and callee_last_regno. */
3280 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3281 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3282
3283 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3284 where imm8u has to be 8-byte alignment. */
3285 sp_adjust = cfun->machine->local_size
3286 + cfun->machine->out_args_size
3287 + cfun->machine->callee_saved_area_padding_bytes;
3288
3289 /* We have to consider alloca issue as well.
3290 If the function does call alloca(), the stack pointer is not fixed.
3291 In that case, we cannot use 'pop25 Re,imm8u' directly.
3292 We have to caculate stack pointer from frame pointer
3293 and then use 'pop25 Re,0'.
3294 Of course, the frame_pointer_needed should be nonzero
3295 if the function calls alloca(). */
3296 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3297 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3298 && !cfun->calls_alloca)
3299 {
3300 /* We can use 'pop25 Re,imm8u'. */
3301
3302 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3303 the pattern 'stack_v3pop' is implementad in nds32.md.
3304 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3305 nds32_emit_stack_v3pop (Rb, Re,
3306 GEN_INT (14), GEN_INT (sp_adjust));
3307 }
3308 else
3309 {
3310 /* We have to use 'pop25 Re,0', and prior to it,
3311 we must expand one more instruction to adjust $sp. */
3312
3313 if (frame_pointer_needed)
3314 {
3315 /* adjust $sp = $fp - 4 ($fp size)
3316 - 4 ($gp size)
3317 - 4 ($lp size)
3318 - (4 * n) (callee-saved registers)
3319 Note: No need to adjust
3320 cfun->machine->callee_saved_area_padding_bytes,
3321 because we want to adjust stack pointer
3322 to the position for pop instruction. */
3323 sp_adjust = cfun->machine->fp_size
3324 + cfun->machine->gp_size
3325 + cfun->machine->lp_size
3326 + cfun->machine->callee_saved_regs_size;
3327 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3328 hard_frame_pointer_rtx,
3329 GEN_INT (-1 * sp_adjust));
3330 /* Emit rtx into instructions list and receive INSN rtx form. */
3331 sp_adjust_insn = emit_insn (sp_adjust_insn);
3332 }
3333 else
3334 {
3335 /* If frame pointer is NOT needed,
3336 we cannot calculate the sp adjustment from frame pointer.
3337 Instead, we calculate the adjustment by local_size,
3338 out_args_size, and callee_saved_area_padding_bytes.
3339 Notice that such sp adjustment value may be out of range,
3340 so we have to deal with it as well. */
3341
3342 /* Adjust $sp = $sp + local_size + out_args_size
3343 + callee_saved_area_padding_bytes. */
3344 sp_adjust = cfun->machine->local_size
3345 + cfun->machine->out_args_size
3346 + cfun->machine->callee_saved_area_padding_bytes;
3347 /* sp_adjust value may be out of range of the addi instruction,
3348 create alternative add behavior with TA_REGNUM if necessary,
3349 using POSITIVE value to tell that we are increasing address. */
3350 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3351 if (sp_adjust)
3352 {
3353 /* Generate sp adjustment instruction
3354 if and only if sp_adjust != 0. */
3355 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3356 stack_pointer_rtx,
3357 GEN_INT (sp_adjust));
3358 /* Emit rtx into instructions list and receive INSN rtx form. */
3359 sp_adjust_insn = emit_insn (sp_adjust_insn);
3360 }
3361 }
3362
3363 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3364 the pattern 'stack_v3pop' is implementad in nds32.md. */
3365 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3366 nds32_emit_stack_v3pop (Rb, Re,
3367 GEN_INT (14), GEN_INT (0));
3368 }
3369 }
3370
3371 /* ------------------------------------------------------------------------ */
3372
3373 /* Function to test 333-form for load/store instructions.
3374 This is auxiliary extern function for auxiliary macro in nds32.h.
3375 Because it is a little complicated, we use function instead of macro. */
3376 bool
3377 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
3378 {
3379 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3380 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3381 {
3382 if (GET_MODE_SIZE (mode) == 4)
3383 return satisfies_constraint_Iu05 (imm);
3384
3385 if (GET_MODE_SIZE (mode) == 2)
3386 return satisfies_constraint_Iu04 (imm);
3387
3388 if (GET_MODE_SIZE (mode) == 1)
3389 return satisfies_constraint_Iu03 (imm);
3390 }
3391
3392 return false;
3393 }
3394
3395
3396 /* Computing the Length of an Insn.
3397 Modifies the length assigned to instruction INSN.
3398 LEN is the initially computed length of the insn. */
3399 int
3400 nds32_adjust_insn_length (rtx_insn *insn, int length)
3401 {
3402 rtx src, dst;
3403
3404 switch (recog_memoized (insn))
3405 {
3406 case CODE_FOR_move_df:
3407 case CODE_FOR_move_di:
3408 /* Adjust length of movd44 to 2. */
3409 src = XEXP (PATTERN (insn), 1);
3410 dst = XEXP (PATTERN (insn), 0);
3411
3412 if (REG_P (src)
3413 && REG_P (dst)
3414 && (REGNO (src) % 2) == 0
3415 && (REGNO (dst) % 2) == 0)
3416 length = 2;
3417 break;
3418
3419 default:
3420 break;
3421 }
3422
3423 return length;
3424 }
3425
3426
3427 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3428 int
3429 nds32_target_alignment (rtx label)
3430 {
3431 rtx_insn *insn;
3432
3433 if (optimize_size)
3434 return 0;
3435
3436 insn = next_active_insn (label);
3437
3438 if (insn == 0)
3439 return 0;
3440 else if ((get_attr_length (insn) % 4) == 0)
3441 return 2;
3442 else
3443 return 0;
3444 }
3445
3446 /* ------------------------------------------------------------------------ */
3447
3448 /* PART 5: Initialize target hook structure and definitions. */
3449 \f
3450 /* Controlling the Compilation Driver. */
3451
3452 \f
3453 /* Run-time Target Specification. */
3454
3455 \f
3456 /* Defining Data Structures for Per-function Information. */
3457
3458 \f
3459 /* Storage Layout. */
3460
3461 #undef TARGET_PROMOTE_FUNCTION_MODE
3462 #define TARGET_PROMOTE_FUNCTION_MODE \
3463 default_promote_function_mode_always_promote
3464
3465 \f
3466 /* Layout of Source Language Data Types. */
3467
3468 \f
3469 /* Register Usage. */
3470
3471 /* -- Basic Characteristics of Registers. */
3472
3473 /* -- Order of Allocation of Registers. */
3474
3475 /* -- How Values Fit in Registers. */
3476
3477 /* -- Handling Leaf Functions. */
3478
3479 /* -- Registers That Form a Stack. */
3480
3481 \f
3482 /* Register Classes. */
3483
3484 #undef TARGET_CLASS_MAX_NREGS
3485 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3486
3487 #undef TARGET_LRA_P
3488 #define TARGET_LRA_P hook_bool_void_true
3489
3490 #undef TARGET_REGISTER_PRIORITY
3491 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3492
3493 \f
3494 /* Obsolete Macros for Defining Constraints. */
3495
3496 \f
3497 /* Stack Layout and Calling Conventions. */
3498
3499 /* -- Basic Stack Layout. */
3500
3501 /* -- Exception Handling Support. */
3502
3503 /* -- Specifying How Stack Checking is Done. */
3504
3505 /* -- Registers That Address the Stack Frame. */
3506
3507 /* -- Eliminating Frame Pointer and Arg Pointer. */
3508
3509 #undef TARGET_CAN_ELIMINATE
3510 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3511
3512 /* -- Passing Function Arguments on the Stack. */
3513
3514 /* -- Passing Arguments in Registers. */
3515
3516 #undef TARGET_FUNCTION_ARG
3517 #define TARGET_FUNCTION_ARG nds32_function_arg
3518
3519 #undef TARGET_MUST_PASS_IN_STACK
3520 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3521
3522 #undef TARGET_ARG_PARTIAL_BYTES
3523 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3524
3525 #undef TARGET_FUNCTION_ARG_ADVANCE
3526 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3527
3528 #undef TARGET_FUNCTION_ARG_BOUNDARY
3529 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3530
3531 /* -- How Scalar Function Values Are Returned. */
3532
3533 #undef TARGET_FUNCTION_VALUE
3534 #define TARGET_FUNCTION_VALUE nds32_function_value
3535
3536 #undef TARGET_LIBCALL_VALUE
3537 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3538
3539 #undef TARGET_FUNCTION_VALUE_REGNO_P
3540 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3541
3542 /* -- How Large Values Are Returned. */
3543
3544 /* -- Caller-Saves Register Allocation. */
3545
3546 /* -- Function Entry and Exit. */
3547
3548 #undef TARGET_ASM_FUNCTION_PROLOGUE
3549 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3550
3551 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3552 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3553
3554 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3555 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3556
3557 #undef TARGET_ASM_FUNCTION_EPILOGUE
3558 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3559
3560 #undef TARGET_ASM_OUTPUT_MI_THUNK
3561 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3562
3563 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3564 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3565
3566 /* -- Generating Code for Profiling. */
3567
3568 /* -- Permitting tail calls. */
3569
3570 #undef TARGET_WARN_FUNC_RETURN
3571 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3572
3573 /* Stack smashing protection. */
3574
3575 \f
3576 /* Implementing the Varargs Macros. */
3577
3578 #undef TARGET_SETUP_INCOMING_VARARGS
3579 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3580
3581 #undef TARGET_STRICT_ARGUMENT_NAMING
3582 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3583
3584 \f
3585 /* Trampolines for Nested Functions. */
3586
3587 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3588 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3589
3590 #undef TARGET_TRAMPOLINE_INIT
3591 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3592
3593 \f
3594 /* Implicit Calls to Library Routines. */
3595
3596 \f
3597 /* Addressing Modes. */
3598
3599 #undef TARGET_LEGITIMATE_ADDRESS_P
3600 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3601
3602 \f
3603 /* Anchored Addresses. */
3604
3605 \f
3606 /* Condition Code Status. */
3607
3608 /* -- Representation of condition codes using (cc0). */
3609
3610 /* -- Representation of condition codes using registers. */
3611
3612 /* -- Macros to control conditional execution. */
3613
3614 \f
3615 /* Describing Relative Costs of Operations. */
3616
3617 #undef TARGET_REGISTER_MOVE_COST
3618 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3619
3620 #undef TARGET_MEMORY_MOVE_COST
3621 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3622
3623 #undef TARGET_RTX_COSTS
3624 #define TARGET_RTX_COSTS nds32_rtx_costs
3625
3626 #undef TARGET_ADDRESS_COST
3627 #define TARGET_ADDRESS_COST nds32_address_cost
3628
3629 \f
3630 /* Adjusting the Instruction Scheduler. */
3631
3632 \f
3633 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3634
3635 \f
3636 /* Position Independent Code. */
3637
3638 \f
3639 /* Defining the Output Assembler Language. */
3640
3641 /* -- The Overall Framework of an Assembler File. */
3642
3643 #undef TARGET_ASM_FILE_START
3644 #define TARGET_ASM_FILE_START nds32_asm_file_start
3645 #undef TARGET_ASM_FILE_END
3646 #define TARGET_ASM_FILE_END nds32_asm_file_end
3647
3648 /* -- Output of Data. */
3649
3650 #undef TARGET_ASM_ALIGNED_HI_OP
3651 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3652
3653 #undef TARGET_ASM_ALIGNED_SI_OP
3654 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3655
3656 /* -- Output of Uninitialized Variables. */
3657
3658 /* -- Output and Generation of Labels. */
3659
3660 #undef TARGET_ASM_GLOBALIZE_LABEL
3661 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3662
3663 /* -- How Initialization Functions Are Handled. */
3664
3665 /* -- Macros Controlling Initialization Routines. */
3666
3667 /* -- Output of Assembler Instructions. */
3668
3669 #undef TARGET_PRINT_OPERAND
3670 #define TARGET_PRINT_OPERAND nds32_print_operand
3671 #undef TARGET_PRINT_OPERAND_ADDRESS
3672 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3673
3674 /* -- Output of Dispatch Tables. */
3675
3676 /* -- Assembler Commands for Exception Regions. */
3677
3678 /* -- Assembler Commands for Alignment. */
3679
3680 \f
3681 /* Controlling Debugging Information Format. */
3682
3683 /* -- Macros Affecting All Debugging Formats. */
3684
3685 /* -- Specific Options for DBX Output. */
3686
3687 /* -- Open-Ended Hooks for DBX Format. */
3688
3689 /* -- File Names in DBX Format. */
3690
3691 /* -- Macros for SDB and DWARF Output. */
3692
3693 /* -- Macros for VMS Debug Format. */
3694
3695 \f
3696 /* Cross Compilation and Floating Point. */
3697
3698 \f
3699 /* Mode Switching Instructions. */
3700
3701 \f
3702 /* Defining target-specific uses of __attribute__. */
3703
3704 #undef TARGET_ATTRIBUTE_TABLE
3705 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3706
3707 #undef TARGET_MERGE_DECL_ATTRIBUTES
3708 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3709
3710 #undef TARGET_INSERT_ATTRIBUTES
3711 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3712
3713 #undef TARGET_OPTION_PRAGMA_PARSE
3714 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3715
3716 #undef TARGET_OPTION_OVERRIDE
3717 #define TARGET_OPTION_OVERRIDE nds32_option_override
3718
3719 \f
3720 /* Emulating TLS. */
3721
3722 \f
3723 /* Defining coprocessor specifics for MIPS targets. */
3724
3725 \f
3726 /* Parameters for Precompiled Header Validity Checking. */
3727
3728 \f
3729 /* C++ ABI parameters. */
3730
3731 \f
3732 /* Adding support for named address spaces. */
3733
3734 \f
3735 /* Miscellaneous Parameters. */
3736
3737 #undef TARGET_INIT_BUILTINS
3738 #define TARGET_INIT_BUILTINS nds32_init_builtins
3739
3740 #undef TARGET_EXPAND_BUILTIN
3741 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3742
3743 \f
3744 /* ------------------------------------------------------------------------ */
3745
3746 /* Initialize the GCC target structure. */
3747
3748 struct gcc_target targetm = TARGET_INITIALIZER;
3749
3750 /* ------------------------------------------------------------------------ */