[NDS32] Deal with nameless arguments in nds32_function_arg and nds32_function_arg_adv...
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob509b4a5bfc519ab142cd71d2a609bf7126866963
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.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "stor-layout.h"
29 #include "varasm.h"
30 #include "calls.h"
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h" /* Required by recog.h. */
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h" /* For DFA state_t. */
38 #include "insn-codes.h" /* For CODE_FOR_xxx. */
39 #include "reload.h" /* For push_reload(). */
40 #include "flags.h"
41 #include "function.h"
42 #include "expr.h"
43 #include "recog.h"
44 #include "diagnostic-core.h"
45 #include "df.h"
46 #include "tm_p.h"
47 #include "tm-constrs.h"
48 #include "optabs.h" /* For GEN_FCN. */
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h" /* For add_builtin_function(). */
52 #include "ggc.h"
53 #include "builtins.h"
55 /* ------------------------------------------------------------------------ */
57 /* This file is divided into five parts:
59 PART 1: Auxiliary static variable definitions and
60 target hook static variable definitions.
62 PART 2: Auxiliary static function definitions.
64 PART 3: Implement target hook stuff definitions.
66 PART 4: Implemet extern function definitions,
67 the prototype is in nds32-protos.h.
69 PART 5: Initialize target hook structure and definitions. */
71 /* ------------------------------------------------------------------------ */
73 /* PART 1: Auxiliary static variable definitions and
74 target hook static variable definitions. */
76 /* Define intrinsic register names.
77 Please refer to nds32_intrinsic.h file, the index is corresponding to
78 'enum nds32_intrinsic_registers' data type values.
79 NOTE that the base value starting from 1024. */
80 static const char * const nds32_intrinsic_register_names[] =
82 "$PSW", "$IPSW", "$ITYPE", "$IPC"
85 /* Defining target-specific uses of __attribute__. */
86 static const struct attribute_spec nds32_attribute_table[] =
88 /* Syntax: { name, min_len, max_len, decl_required, type_required,
89 function_type_required, handler, affects_type_identity } */
91 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
92 { "interrupt", 1, 64, false, false, false, NULL, false },
93 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
94 { "exception", 1, 8, false, false, false, NULL, false },
95 /* Argument is user's interrupt numbers. The vector number is always 0. */
96 { "reset", 1, 1, false, false, false, NULL, false },
98 /* The attributes describing isr nested type. */
99 { "nested", 0, 0, false, false, false, NULL, false },
100 { "not_nested", 0, 0, false, false, false, NULL, false },
101 { "nested_ready", 0, 0, false, false, false, NULL, false },
103 /* The attributes describing isr register save scheme. */
104 { "save_all", 0, 0, false, false, false, NULL, false },
105 { "partial_save", 0, 0, false, false, false, NULL, false },
107 /* The attributes used by reset attribute. */
108 { "nmi", 1, 1, false, false, false, NULL, false },
109 { "warm", 1, 1, false, false, false, NULL, false },
111 /* The attribute telling no prologue/epilogue. */
112 { "naked", 0, 0, false, false, false, NULL, false },
114 /* The last attribute spec is set to be NULL. */
115 { NULL, 0, 0, false, false, false, NULL, false }
119 /* ------------------------------------------------------------------------ */
121 /* PART 2: Auxiliary static function definitions. */
123 /* Function to save and restore machine-specific function data. */
124 static struct machine_function *
125 nds32_init_machine_status (void)
127 struct machine_function *machine;
128 machine = ggc_cleared_alloc<machine_function> ();
130 /* Initially assume this function needs prologue/epilogue. */
131 machine->naked_p = 0;
133 /* Initially assume this function does NOT use fp_as_gp optimization. */
134 machine->fp_as_gp_p = 0;
136 return machine;
139 /* Function to compute stack frame size and
140 store into cfun->machine structure. */
141 static void
142 nds32_compute_stack_frame (void)
144 int r;
145 int block_size;
147 /* Because nds32_compute_stack_frame() will be called from different place,
148 everytime we enter this function, we have to assume this function
149 needs prologue/epilogue. */
150 cfun->machine->naked_p = 0;
152 /* Get variadic arguments size to prepare pretend arguments and
153 we will push them into stack at prologue by ourself. */
154 cfun->machine->va_args_size = crtl->args.pretend_args_size;
155 if (cfun->machine->va_args_size != 0)
157 cfun->machine->va_args_first_regno
158 = NDS32_GPR_ARG_FIRST_REGNUM
159 + NDS32_MAX_GPR_REGS_FOR_ARGS
160 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
161 cfun->machine->va_args_last_regno
162 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
164 else
166 cfun->machine->va_args_first_regno = SP_REGNUM;
167 cfun->machine->va_args_last_regno = SP_REGNUM;
170 /* Important: We need to make sure that varargs area is 8-byte alignment. */
171 block_size = cfun->machine->va_args_size;
172 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
174 cfun->machine->va_args_area_padding_bytes
175 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
178 /* Get local variables, incoming variables, and temporary variables size.
179 Note that we need to make sure it is 8-byte alignment because
180 there may be no padding bytes if we are using LRA. */
181 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
183 /* Get outgoing arguments size. */
184 cfun->machine->out_args_size = crtl->outgoing_args_size;
186 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
187 Check whether $fp is ever live. */
188 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
190 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
191 Check whether we are using PIC code genration. */
192 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
194 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
195 Check whether $lp is ever live. */
196 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
198 /* Initially there is no padding bytes. */
199 cfun->machine->callee_saved_area_padding_bytes = 0;
201 /* Calculate the bytes of saving callee-saved registers on stack. */
202 cfun->machine->callee_saved_regs_size = 0;
203 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
204 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
205 /* Currently, there is no need to check $r28~$r31
206 because we will save them in another way. */
207 for (r = 0; r < 28; r++)
209 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
211 /* Mark the first required callee-saved register
212 (only need to set it once).
213 If first regno == SP_REGNUM, we can tell that
214 it is the first time to be here. */
215 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
216 cfun->machine->callee_saved_regs_first_regno = r;
217 /* Mark the last required callee-saved register. */
218 cfun->machine->callee_saved_regs_last_regno = r;
222 /* Check if this function can omit prologue/epilogue code fragment.
223 If there is 'naked' attribute in this function,
224 we can set 'naked_p' flag to indicate that
225 we do not have to generate prologue/epilogue.
226 Or, if all the following conditions succeed,
227 we can set this function 'naked_p' as well:
228 condition 1: first_regno == last_regno == SP_REGNUM,
229 which means we do not have to save
230 any callee-saved registers.
231 condition 2: Both $lp and $fp are NOT live in this function,
232 which means we do not need to save them and there
233 is no outgoing size.
234 condition 3: There is no local_size, which means
235 we do not need to adjust $sp. */
236 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
237 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
238 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
239 && !df_regs_ever_live_p (FP_REGNUM)
240 && !df_regs_ever_live_p (LP_REGNUM)
241 && cfun->machine->local_size == 0))
243 /* Set this function 'naked_p' and other functions can check this flag.
244 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
245 callee-saved, local size, and outgoing size.
246 The varargs space and ret instruction may still present in
247 the prologue/epilogue expanding. */
248 cfun->machine->naked_p = 1;
250 /* No need to save $fp, $gp, and $lp.
251 We should set these value to be zero
252 so that nds32_initial_elimination_offset() can work properly. */
253 cfun->machine->fp_size = 0;
254 cfun->machine->gp_size = 0;
255 cfun->machine->lp_size = 0;
257 /* If stack usage computation is required,
258 we need to provide the static stack size. */
259 if (flag_stack_usage_info)
260 current_function_static_stack_size = 0;
262 /* No need to do following adjustment, return immediately. */
263 return;
266 /* Adjustment for v3push instructions:
267 If we are using v3push (push25/pop25) instructions,
268 we need to make sure Rb is $r6 and Re is
269 located on $r6, $r8, $r10, or $r14.
270 Some results above will be discarded and recomputed.
271 Note that it is only available under V3/V3M ISA and we
272 DO NOT setup following stuff for isr or variadic function. */
273 if (TARGET_V3PUSH
274 && !nds32_isr_function_p (current_function_decl)
275 && (cfun->machine->va_args_size == 0))
277 /* Recompute:
278 cfun->machine->fp_size
279 cfun->machine->gp_size
280 cfun->machine->lp_size
281 cfun->machine->callee_saved_regs_first_regno
282 cfun->machine->callee_saved_regs_last_regno */
284 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
285 cfun->machine->fp_size = 4;
286 cfun->machine->gp_size = 4;
287 cfun->machine->lp_size = 4;
289 /* Remember to set Rb = $r6. */
290 cfun->machine->callee_saved_regs_first_regno = 6;
292 if (cfun->machine->callee_saved_regs_last_regno <= 6)
294 /* Re = $r6 */
295 cfun->machine->callee_saved_regs_last_regno = 6;
297 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
299 /* Re = $r8 */
300 cfun->machine->callee_saved_regs_last_regno = 8;
302 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
304 /* Re = $r10 */
305 cfun->machine->callee_saved_regs_last_regno = 10;
307 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
309 /* Re = $r14 */
310 cfun->machine->callee_saved_regs_last_regno = 14;
312 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
314 /* If last_regno is SP_REGNUM, which means
315 it is never changed, so set it to Re = $r6. */
316 cfun->machine->callee_saved_regs_last_regno = 6;
318 else
320 /* The program flow should not go here. */
321 gcc_unreachable ();
325 /* We have correctly set callee_saved_regs_first_regno
326 and callee_saved_regs_last_regno.
327 Initially, the callee_saved_regs_size is supposed to be 0.
328 As long as callee_saved_regs_last_regno is not SP_REGNUM,
329 we can update callee_saved_regs_size with new size. */
330 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
332 /* Compute pushed size of callee-saved registers. */
333 cfun->machine->callee_saved_regs_size
334 = 4 * (cfun->machine->callee_saved_regs_last_regno
335 - cfun->machine->callee_saved_regs_first_regno
336 + 1);
339 /* Important: We need to make sure that
340 (fp_size + gp_size + lp_size + callee_saved_regs_size)
341 is 8-byte alignment.
342 If it is not, calculate the padding bytes. */
343 block_size = cfun->machine->fp_size
344 + cfun->machine->gp_size
345 + cfun->machine->lp_size
346 + cfun->machine->callee_saved_regs_size;
347 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
349 cfun->machine->callee_saved_area_padding_bytes
350 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
353 /* If stack usage computation is required,
354 we need to provide the static stack size. */
355 if (flag_stack_usage_info)
357 current_function_static_stack_size
358 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
359 + cfun->machine->local_size
360 + cfun->machine->out_args_size;
364 /* Function to create a parallel rtx pattern
365 which presents stack push multiple behavior.
366 The overall concept are:
367 "push registers to memory",
368 "adjust stack pointer". */
369 static void
370 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4)
372 int regno;
373 int extra_count;
374 int num_use_regs;
375 int par_index;
376 int offset;
377 int save_fp, save_gp, save_lp;
379 rtx reg;
380 rtx mem;
381 rtx push_rtx;
382 rtx adjust_sp_rtx;
383 rtx parallel_insn;
385 /* We need to provide a customized rtx which contains
386 necessary information for data analysis,
387 so we create a parallel rtx like this:
388 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
389 (reg:SI Rb))
390 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
391 (reg:SI Rb+1))
393 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
394 (reg:SI Re))
395 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
396 (reg:SI FP_REGNUM))
397 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
398 (reg:SI GP_REGNUM))
399 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
400 (reg:SI LP_REGNUM))
401 (set (reg:SI SP_REGNUM)
402 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
404 /* Determine whether we need to save $fp, $gp, or $lp. */
405 save_fp = INTVAL (En4) & 0x8;
406 save_gp = INTVAL (En4) & 0x4;
407 save_lp = INTVAL (En4) & 0x2;
409 /* Calculate the number of registers that will be pushed. */
410 extra_count = 0;
411 if (save_fp)
412 extra_count++;
413 if (save_gp)
414 extra_count++;
415 if (save_lp)
416 extra_count++;
417 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
418 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
419 num_use_regs = extra_count;
420 else
421 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
423 /* In addition to used registers,
424 we need one more space for (set sp sp-x) rtx. */
425 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
426 rtvec_alloc (num_use_regs + 1));
427 par_index = 0;
429 /* Initialize offset and start to create push behavior. */
430 offset = -(num_use_regs * 4);
432 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
433 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
435 /* Rb and Re may be SP_REGNUM.
436 We need to break this loop immediately. */
437 if (regno == SP_REGNUM)
438 break;
440 reg = gen_rtx_REG (SImode, regno);
441 mem = gen_frame_mem (SImode, plus_constant (Pmode,
442 stack_pointer_rtx,
443 offset));
444 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
445 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
446 RTX_FRAME_RELATED_P (push_rtx) = 1;
447 offset = offset + 4;
448 par_index++;
451 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
452 if (save_fp)
454 reg = gen_rtx_REG (SImode, FP_REGNUM);
455 mem = gen_frame_mem (SImode, plus_constant (Pmode,
456 stack_pointer_rtx,
457 offset));
458 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
459 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
460 RTX_FRAME_RELATED_P (push_rtx) = 1;
461 offset = offset + 4;
462 par_index++;
464 if (save_gp)
466 reg = gen_rtx_REG (SImode, GP_REGNUM);
467 mem = gen_frame_mem (SImode, plus_constant (Pmode,
468 stack_pointer_rtx,
469 offset));
470 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
471 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
472 RTX_FRAME_RELATED_P (push_rtx) = 1;
473 offset = offset + 4;
474 par_index++;
476 if (save_lp)
478 reg = gen_rtx_REG (SImode, LP_REGNUM);
479 mem = gen_frame_mem (SImode, plus_constant (Pmode,
480 stack_pointer_rtx,
481 offset));
482 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
483 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
484 RTX_FRAME_RELATED_P (push_rtx) = 1;
485 offset = offset + 4;
486 par_index++;
489 /* Create (set sp sp-x). */
491 /* We need to re-calculate the offset value again for adjustment. */
492 offset = -(num_use_regs * 4);
493 adjust_sp_rtx
494 = gen_rtx_SET (VOIDmode,
495 stack_pointer_rtx,
496 plus_constant (Pmode, stack_pointer_rtx, offset));
497 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
498 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
500 parallel_insn = emit_insn (parallel_insn);
502 /* The insn rtx 'parallel_insn' will change frame layout.
503 We need to use RTX_FRAME_RELATED_P so that GCC is able to
504 generate CFI (Call Frame Information) stuff. */
505 RTX_FRAME_RELATED_P (parallel_insn) = 1;
508 /* Function to create a parallel rtx pattern
509 which presents stack pop multiple behavior.
510 The overall concept are:
511 "pop registers from memory",
512 "adjust stack pointer". */
513 static void
514 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
516 int regno;
517 int extra_count;
518 int num_use_regs;
519 int par_index;
520 int offset;
521 int save_fp, save_gp, save_lp;
523 rtx reg;
524 rtx mem;
525 rtx pop_rtx;
526 rtx adjust_sp_rtx;
527 rtx parallel_insn;
528 rtx dwarf = NULL_RTX;
530 /* We need to provide a customized rtx which contains
531 necessary information for data analysis,
532 so we create a parallel rtx like this:
533 (parallel [(set (reg:SI Rb)
534 (mem (reg:SI SP_REGNUM)))
535 (set (reg:SI Rb+1)
536 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
538 (set (reg:SI Re)
539 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
540 (set (reg:SI FP_REGNUM)
541 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
542 (set (reg:SI GP_REGNUM)
543 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
544 (set (reg:SI LP_REGNUM)
545 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
546 (set (reg:SI SP_REGNUM)
547 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
549 /* Determine whether we need to restore $fp, $gp, or $lp. */
550 save_fp = INTVAL (En4) & 0x8;
551 save_gp = INTVAL (En4) & 0x4;
552 save_lp = INTVAL (En4) & 0x2;
554 /* Calculate the number of registers that will be poped. */
555 extra_count = 0;
556 if (save_fp)
557 extra_count++;
558 if (save_gp)
559 extra_count++;
560 if (save_lp)
561 extra_count++;
562 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
563 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
564 num_use_regs = extra_count;
565 else
566 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
568 /* In addition to used registers,
569 we need one more space for (set sp sp+x) rtx. */
570 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
571 rtvec_alloc (num_use_regs + 1));
572 par_index = 0;
574 /* Initialize offset and start to create pop behavior. */
575 offset = 0;
577 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
578 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
580 /* Rb and Re may be SP_REGNUM.
581 We need to break this loop immediately. */
582 if (regno == SP_REGNUM)
583 break;
585 reg = gen_rtx_REG (SImode, regno);
586 mem = gen_frame_mem (SImode, plus_constant (Pmode,
587 stack_pointer_rtx,
588 offset));
589 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
590 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
591 RTX_FRAME_RELATED_P (pop_rtx) = 1;
592 offset = offset + 4;
593 par_index++;
595 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
598 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
599 if (save_fp)
601 reg = gen_rtx_REG (SImode, FP_REGNUM);
602 mem = gen_frame_mem (SImode, plus_constant (Pmode,
603 stack_pointer_rtx,
604 offset));
605 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
606 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
607 RTX_FRAME_RELATED_P (pop_rtx) = 1;
608 offset = offset + 4;
609 par_index++;
611 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
613 if (save_gp)
615 reg = gen_rtx_REG (SImode, GP_REGNUM);
616 mem = gen_frame_mem (SImode, plus_constant (Pmode,
617 stack_pointer_rtx,
618 offset));
619 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
620 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
621 RTX_FRAME_RELATED_P (pop_rtx) = 1;
622 offset = offset + 4;
623 par_index++;
625 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
627 if (save_lp)
629 reg = gen_rtx_REG (SImode, LP_REGNUM);
630 mem = gen_frame_mem (SImode, plus_constant (Pmode,
631 stack_pointer_rtx,
632 offset));
633 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
634 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
635 RTX_FRAME_RELATED_P (pop_rtx) = 1;
636 offset = offset + 4;
637 par_index++;
639 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
642 /* Create (set sp sp+x). */
644 /* The offset value is already in place. No need to re-calculate it. */
645 adjust_sp_rtx
646 = gen_rtx_SET (VOIDmode,
647 stack_pointer_rtx,
648 plus_constant (Pmode, stack_pointer_rtx, offset));
649 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
651 /* Tell gcc we adjust SP in this insn. */
652 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
654 parallel_insn = emit_insn (parallel_insn);
656 /* The insn rtx 'parallel_insn' will change frame layout.
657 We need to use RTX_FRAME_RELATED_P so that GCC is able to
658 generate CFI (Call Frame Information) stuff. */
659 RTX_FRAME_RELATED_P (parallel_insn) = 1;
661 /* Add CFI info by manual. */
662 REG_NOTES (parallel_insn) = dwarf;
665 /* Function to create a parallel rtx pattern
666 which presents stack v3push behavior.
667 The overall concept are:
668 "push registers to memory",
669 "adjust stack pointer". */
670 static void
671 nds32_emit_stack_v3push (rtx Rb,
672 rtx Re,
673 rtx En4 ATTRIBUTE_UNUSED,
674 rtx imm8u)
676 int regno;
677 int num_use_regs;
678 int par_index;
679 int offset;
681 rtx reg;
682 rtx mem;
683 rtx push_rtx;
684 rtx adjust_sp_rtx;
685 rtx parallel_insn;
687 /* We need to provide a customized rtx which contains
688 necessary information for data analysis,
689 so we create a parallel rtx like this:
690 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
691 (reg:SI Rb))
692 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
693 (reg:SI Rb+1))
695 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
696 (reg:SI Re))
697 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
698 (reg:SI FP_REGNUM))
699 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
700 (reg:SI GP_REGNUM))
701 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
702 (reg:SI LP_REGNUM))
703 (set (reg:SI SP_REGNUM)
704 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
706 /* Calculate the number of registers that will be pushed.
707 Since $fp, $gp, and $lp is always pushed with v3push instruction,
708 we need to count these three registers.
709 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
710 So there is no need to worry about Rb=Re=SP_REGNUM case. */
711 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
713 /* In addition to used registers,
714 we need one more space for (set sp sp-x-imm8u) rtx. */
715 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
716 rtvec_alloc (num_use_regs + 1));
717 par_index = 0;
719 /* Initialize offset and start to create push behavior. */
720 offset = -(num_use_regs * 4);
722 /* Create (set mem regX) from Rb, Rb+1 up to Re.
723 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
724 So there is no need to worry about Rb=Re=SP_REGNUM case. */
725 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
727 reg = gen_rtx_REG (SImode, regno);
728 mem = gen_frame_mem (SImode, plus_constant (Pmode,
729 stack_pointer_rtx,
730 offset));
731 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
732 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
733 RTX_FRAME_RELATED_P (push_rtx) = 1;
734 offset = offset + 4;
735 par_index++;
738 /* Create (set mem fp). */
739 reg = gen_rtx_REG (SImode, FP_REGNUM);
740 mem = gen_frame_mem (SImode, plus_constant (Pmode,
741 stack_pointer_rtx,
742 offset));
743 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
744 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
745 RTX_FRAME_RELATED_P (push_rtx) = 1;
746 offset = offset + 4;
747 par_index++;
748 /* Create (set mem gp). */
749 reg = gen_rtx_REG (SImode, GP_REGNUM);
750 mem = gen_frame_mem (SImode, plus_constant (Pmode,
751 stack_pointer_rtx,
752 offset));
753 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
754 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
755 RTX_FRAME_RELATED_P (push_rtx) = 1;
756 offset = offset + 4;
757 par_index++;
758 /* Create (set mem lp). */
759 reg = gen_rtx_REG (SImode, LP_REGNUM);
760 mem = gen_frame_mem (SImode, plus_constant (Pmode,
761 stack_pointer_rtx,
762 offset));
763 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
764 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
765 RTX_FRAME_RELATED_P (push_rtx) = 1;
766 offset = offset + 4;
767 par_index++;
769 /* Create (set sp sp-x-imm8u). */
771 /* We need to re-calculate the offset value again for adjustment. */
772 offset = -(num_use_regs * 4);
773 adjust_sp_rtx
774 = gen_rtx_SET (VOIDmode,
775 stack_pointer_rtx,
776 plus_constant (Pmode,
777 stack_pointer_rtx,
778 offset - INTVAL (imm8u)));
779 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
780 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
782 parallel_insn = emit_insn (parallel_insn);
784 /* The insn rtx 'parallel_insn' will change frame layout.
785 We need to use RTX_FRAME_RELATED_P so that GCC is able to
786 generate CFI (Call Frame Information) stuff. */
787 RTX_FRAME_RELATED_P (parallel_insn) = 1;
790 /* Function to create a parallel rtx pattern
791 which presents stack v3pop behavior.
792 The overall concept are:
793 "pop registers from memory",
794 "adjust stack pointer". */
795 static void
796 nds32_emit_stack_v3pop (rtx Rb,
797 rtx Re,
798 rtx En4 ATTRIBUTE_UNUSED,
799 rtx imm8u)
801 int regno;
802 int num_use_regs;
803 int par_index;
804 int offset;
806 rtx reg;
807 rtx mem;
808 rtx pop_rtx;
809 rtx adjust_sp_rtx;
810 rtx parallel_insn;
811 rtx dwarf = NULL_RTX;
813 /* We need to provide a customized rtx which contains
814 necessary information for data analysis,
815 so we create a parallel rtx like this:
816 (parallel [(set (reg:SI Rb)
817 (mem (reg:SI SP_REGNUM)))
818 (set (reg:SI Rb+1)
819 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
821 (set (reg:SI Re)
822 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
823 (set (reg:SI FP_REGNUM)
824 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
825 (set (reg:SI GP_REGNUM)
826 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
827 (set (reg:SI LP_REGNUM)
828 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
829 (set (reg:SI SP_REGNUM)
830 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
832 /* Calculate the number of registers that will be poped.
833 Since $fp, $gp, and $lp is always poped with v3pop instruction,
834 we need to count these three registers.
835 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
836 So there is no need to worry about Rb=Re=SP_REGNUM case. */
837 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
839 /* In addition to used registers,
840 we need one more space for (set sp sp+x+imm8u) rtx. */
841 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
842 rtvec_alloc (num_use_regs + 1));
843 par_index = 0;
845 /* Initialize offset and start to create pop behavior. */
846 offset = 0;
848 /* Create (set regX mem) from Rb, Rb+1 up to Re.
849 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
850 So there is no need to worry about Rb=Re=SP_REGNUM case. */
851 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
853 reg = gen_rtx_REG (SImode, regno);
854 mem = gen_frame_mem (SImode, plus_constant (Pmode,
855 stack_pointer_rtx,
856 offset));
857 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
858 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
859 RTX_FRAME_RELATED_P (pop_rtx) = 1;
860 offset = offset + 4;
861 par_index++;
863 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
866 /* Create (set fp mem). */
867 reg = gen_rtx_REG (SImode, FP_REGNUM);
868 mem = gen_frame_mem (SImode, plus_constant (Pmode,
869 stack_pointer_rtx,
870 offset));
871 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
872 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
873 RTX_FRAME_RELATED_P (pop_rtx) = 1;
874 offset = offset + 4;
875 par_index++;
876 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
878 /* Create (set gp mem). */
879 reg = gen_rtx_REG (SImode, GP_REGNUM);
880 mem = gen_frame_mem (SImode, plus_constant (Pmode,
881 stack_pointer_rtx,
882 offset));
883 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
884 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
885 RTX_FRAME_RELATED_P (pop_rtx) = 1;
886 offset = offset + 4;
887 par_index++;
888 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
890 /* Create (set lp mem ). */
891 reg = gen_rtx_REG (SImode, LP_REGNUM);
892 mem = gen_frame_mem (SImode, plus_constant (Pmode,
893 stack_pointer_rtx,
894 offset));
895 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
896 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
897 RTX_FRAME_RELATED_P (pop_rtx) = 1;
898 offset = offset + 4;
899 par_index++;
900 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
902 /* Create (set sp sp+x+imm8u). */
904 /* The offset value is already in place. No need to re-calculate it. */
905 adjust_sp_rtx
906 = gen_rtx_SET (VOIDmode,
907 stack_pointer_rtx,
908 plus_constant (Pmode,
909 stack_pointer_rtx,
910 offset + INTVAL (imm8u)));
911 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
913 /* Tell gcc we adjust SP in this insn. */
914 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
916 parallel_insn = emit_insn (parallel_insn);
918 /* The insn rtx 'parallel_insn' will change frame layout.
919 We need to use RTX_FRAME_RELATED_P so that GCC is able to
920 generate CFI (Call Frame Information) stuff. */
921 RTX_FRAME_RELATED_P (parallel_insn) = 1;
923 /* Add CFI info by manual. */
924 REG_NOTES (parallel_insn) = dwarf;
927 /* Function that may creates more instructions
928 for large value on adjusting stack pointer.
930 In nds32 target, 'addi' can be used for stack pointer
931 adjustment in prologue/epilogue stage.
932 However, sometimes there are too many local variables so that
933 the adjustment value is not able to be fit in the 'addi' instruction.
934 One solution is to move value into a register
935 and then use 'add' instruction.
936 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
937 Also, we need to return zero for sp adjustment so that
938 proglogue/epilogue knows there is no need to create 'addi' instruction. */
939 static int
940 nds32_force_addi_stack_int (int full_value)
942 int adjust_value;
944 rtx tmp_reg;
945 rtx sp_adjust_insn;
947 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
949 /* The value is not able to fit in single addi instruction.
950 Create more instructions of moving value into a register
951 and then add stack pointer with it. */
953 /* $r15 is going to be temporary register to hold the value. */
954 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
956 /* Create one more instruction to move value
957 into the temporary register. */
958 emit_move_insn (tmp_reg, GEN_INT (full_value));
960 /* Create new 'add' rtx. */
961 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
962 stack_pointer_rtx,
963 tmp_reg);
964 /* Emit rtx into insn list and receive its transformed insn rtx. */
965 sp_adjust_insn = emit_insn (sp_adjust_insn);
967 /* At prologue, we need to tell GCC that this is frame related insn,
968 so that we can consider this instruction to output debug information.
969 If full_value is NEGATIVE, it means this function
970 is invoked by expand_prologue. */
971 if (full_value < 0)
973 /* Because (tmp_reg <- full_value) may be split into two
974 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
975 We need to construct another (sp <- sp + full_value)
976 and then insert it into sp_adjust_insn's reg note to
977 represent a frame related expression.
978 GCC knows how to refer it and output debug information. */
980 rtx plus_rtx;
981 rtx set_rtx;
983 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
984 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
985 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
987 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
990 /* We have used alternative way to adjust stack pointer value.
991 Return zero so that prologue/epilogue
992 will not generate other instructions. */
993 return 0;
995 else
997 /* The value is able to fit in addi instruction.
998 However, remember to make it to be positive value
999 because we want to return 'adjustment' result. */
1000 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1002 return adjust_value;
1006 /* Return true if MODE/TYPE need double word alignment. */
1007 static bool
1008 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
1010 unsigned int align;
1012 /* Pick up the alignment according to the mode or type. */
1013 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1015 return (align > PARM_BOUNDARY);
1018 /* Return true if FUNC is a naked function. */
1019 static bool
1020 nds32_naked_function_p (tree func)
1022 tree t;
1024 if (TREE_CODE (func) != FUNCTION_DECL)
1025 abort ();
1027 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1029 return (t != NULL_TREE);
1032 /* Function that check if 'X' is a valid address register.
1033 The variable 'STRICT' is very important to
1034 make decision for register number.
1036 STRICT : true
1037 => We are in reload pass or after reload pass.
1038 The register number should be strictly limited in general registers.
1040 STRICT : false
1041 => Before reload pass, we are free to use any register number. */
1042 static bool
1043 nds32_address_register_rtx_p (rtx x, bool strict)
1045 int regno;
1047 if (GET_CODE (x) != REG)
1048 return false;
1050 regno = REGNO (x);
1052 if (strict)
1053 return REGNO_OK_FOR_BASE_P (regno);
1054 else
1055 return true;
1058 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1060 OUTER_MODE : Machine mode of outer address rtx.
1061 INDEX : Check if this rtx is valid to be a index for address.
1062 STRICT : If it is true, we are in reload pass or after reload pass. */
1063 static bool
1064 nds32_legitimate_index_p (enum machine_mode outer_mode,
1065 rtx index,
1066 bool strict)
1068 int regno;
1069 rtx op0;
1070 rtx op1;
1072 switch (GET_CODE (index))
1074 case REG:
1075 regno = REGNO (index);
1076 /* If we are in reload pass or after reload pass,
1077 we need to limit it to general register. */
1078 if (strict)
1079 return REGNO_OK_FOR_INDEX_P (regno);
1080 else
1081 return true;
1083 case CONST_INT:
1084 /* The alignment of the integer value is determined by 'outer_mode'. */
1085 if (GET_MODE_SIZE (outer_mode) == 1)
1087 /* Further check if the value is legal for the 'outer_mode'. */
1088 if (!satisfies_constraint_Is15 (index))
1089 return false;
1091 /* Pass all test, the value is valid, return true. */
1092 return true;
1094 if (GET_MODE_SIZE (outer_mode) == 2
1095 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1097 /* Further check if the value is legal for the 'outer_mode'. */
1098 if (!satisfies_constraint_Is16 (index))
1099 return false;
1101 /* Pass all test, the value is valid, return true. */
1102 return true;
1104 if (GET_MODE_SIZE (outer_mode) == 4
1105 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1107 /* Further check if the value is legal for the 'outer_mode'. */
1108 if (!satisfies_constraint_Is17 (index))
1109 return false;
1111 /* Pass all test, the value is valid, return true. */
1112 return true;
1114 if (GET_MODE_SIZE (outer_mode) == 8
1115 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1117 /* Further check if the value is legal for the 'outer_mode'. */
1118 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1119 SImode)))
1120 return false;
1122 /* Pass all test, the value is valid, return true. */
1123 return true;
1126 return false;
1128 case MULT:
1129 op0 = XEXP (index, 0);
1130 op1 = XEXP (index, 1);
1132 if (REG_P (op0) && CONST_INT_P (op1))
1134 int multiplier;
1135 multiplier = INTVAL (op1);
1137 /* We only allow (mult reg const_int_1)
1138 or (mult reg const_int_2) or (mult reg const_int_4). */
1139 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1140 return false;
1142 regno = REGNO (op0);
1143 /* Limit it in general registers if we are
1144 in reload pass or after reload pass. */
1145 if(strict)
1146 return REGNO_OK_FOR_INDEX_P (regno);
1147 else
1148 return true;
1151 return false;
1153 case ASHIFT:
1154 op0 = XEXP (index, 0);
1155 op1 = XEXP (index, 1);
1157 if (REG_P (op0) && CONST_INT_P (op1))
1159 int sv;
1160 /* op1 is already the sv value for use to do left shift. */
1161 sv = INTVAL (op1);
1163 /* We only allow (ashift reg const_int_0)
1164 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1165 if (sv != 0 && sv != 1 && sv !=2)
1166 return false;
1168 regno = REGNO (op0);
1169 /* Limit it in general registers if we are
1170 in reload pass or after reload pass. */
1171 if(strict)
1172 return REGNO_OK_FOR_INDEX_P (regno);
1173 else
1174 return true;
1177 return false;
1179 default:
1180 return false;
1184 /* ------------------------------------------------------------------------ */
1186 /* PART 3: Implement target hook stuff definitions. */
1188 /* Register Classes. */
1190 static unsigned char
1191 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1192 enum machine_mode mode)
1194 /* Return the maximum number of consecutive registers
1195 needed to represent "mode" in a register of "rclass". */
1196 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1199 static int
1200 nds32_register_priority (int hard_regno)
1202 /* Encourage to use r0-r7 for LRA when optimize for size. */
1203 if (optimize_size && hard_regno < 8)
1204 return 4;
1205 return 3;
1209 /* Stack Layout and Calling Conventions. */
1211 /* There are three kinds of pointer concepts using in GCC compiler:
1213 frame pointer: A pointer to the first location of local variables.
1214 stack pointer: A pointer to the top of a stack frame.
1215 argument pointer: A pointer to the incoming arguments.
1217 In nds32 target calling convention, we are using 8-byte alignment.
1218 Besides, we would like to have each stack frame of a function includes:
1220 [Block A]
1221 1. previous hard frame pointer
1222 2. return address
1223 3. callee-saved registers
1224 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1225 and save it at
1226 cfun->machine->callee_saved_area_padding_bytes)
1228 [Block B]
1229 1. local variables
1230 2. spilling location
1231 3. <padding bytes> (it will be calculated by GCC itself)
1232 4. incoming arguments
1233 5. <padding bytes> (it will be calculated by GCC itself)
1235 [Block C]
1236 1. <padding bytes> (it will be calculated by GCC itself)
1237 2. outgoing arguments
1239 We 'wrap' these blocks together with
1240 hard frame pointer ($r28) and stack pointer ($r31).
1241 By applying the basic frame/stack/argument pointers concept,
1242 the layout of a stack frame shoule be like this:
1245 old stack pointer -> ----
1246 | | \
1247 | | saved arguments for
1248 | | vararg functions
1249 | | /
1250 hard frame pointer -> --
1251 & argument pointer | | \
1252 | | previous hardware frame pointer
1253 | | return address
1254 | | callee-saved registers
1255 | | /
1256 frame pointer -> --
1257 | | \
1258 | | local variables
1259 | | and incoming arguments
1260 | | /
1262 | | \
1263 | | outgoing
1264 | | arguments
1265 | | /
1266 stack pointer -> ----
1268 $SFP and $AP are used to represent frame pointer and arguments pointer,
1269 which will be both eliminated as hard frame pointer. */
1271 /* -- Eliminating Frame Pointer and Arg Pointer. */
1273 static bool
1274 nds32_can_eliminate (const int from_reg, const int to_reg)
1276 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1277 return true;
1279 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1280 return true;
1282 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1283 return true;
1285 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1286 return true;
1288 return false;
1291 /* -- Passing Arguments in Registers. */
1293 static rtx
1294 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1295 const_tree type, bool named)
1297 unsigned int regno;
1298 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1300 /* The last time this hook is called,
1301 it is called with MODE == VOIDmode. */
1302 if (mode == VOIDmode)
1303 return NULL_RTX;
1305 /* For nameless arguments, we need to take care it individually. */
1306 if (!named)
1308 /* If we are under hard float abi, we have arguments passed on the
1309 stack and all situation can be handled by GCC itself. */
1310 if (TARGET_HARD_FLOAT)
1311 return NULL_RTX;
1313 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1315 /* If we still have enough registers to pass argument, pick up
1316 next available register number. */
1317 regno
1318 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1319 return gen_rtx_REG (mode, regno);
1322 /* No register available, return NULL_RTX.
1323 The compiler will use stack to pass argument instead. */
1324 return NULL_RTX;
1327 /* The following is to handle named argument.
1328 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1329 are different. */
1330 if (TARGET_HARD_FLOAT)
1332 /* Currently we have not implemented hard float yet. */
1333 gcc_unreachable ();
1335 else
1337 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1338 argument. Since we allow to pass argument partially in registers,
1339 we can just return it if there are still registers available. */
1340 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1342 /* Pick up the next available register number. */
1343 regno
1344 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1345 return gen_rtx_REG (mode, regno);
1350 /* No register available, return NULL_RTX.
1351 The compiler will use stack to pass argument instead. */
1352 return NULL_RTX;
1355 static void
1356 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1357 const_tree type, bool named)
1359 enum machine_mode sub_mode;
1360 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1362 if (named)
1364 /* We need to further check TYPE and MODE so that we can determine
1365 which kind of register we shall advance. */
1366 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1367 sub_mode = TYPE_MODE (TREE_TYPE (type));
1368 else
1369 sub_mode = mode;
1371 /* Under hard float abi, we may advance FPR registers. */
1372 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1374 /* Currently we have not implemented hard float yet. */
1375 gcc_unreachable ();
1377 else
1379 cum->gpr_offset
1380 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1381 - NDS32_GPR_ARG_FIRST_REGNUM
1382 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1385 else
1387 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1388 we can advance next register as well so that caller is
1389 able to pass arguments in registers and callee must be
1390 in charge of pushing all of them into stack. */
1391 if (!TARGET_HARD_FLOAT)
1393 cum->gpr_offset
1394 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1395 - NDS32_GPR_ARG_FIRST_REGNUM
1396 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1401 static unsigned int
1402 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1404 return (nds32_needs_double_word_align (mode, type)
1405 ? NDS32_DOUBLE_WORD_ALIGNMENT
1406 : PARM_BOUNDARY);
1409 /* -- How Scalar Function Values Are Returned. */
1411 static rtx
1412 nds32_function_value (const_tree ret_type,
1413 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1414 bool outgoing ATTRIBUTE_UNUSED)
1416 enum machine_mode mode;
1417 int unsignedp;
1419 mode = TYPE_MODE (ret_type);
1420 unsignedp = TYPE_UNSIGNED (ret_type);
1422 mode = promote_mode (ret_type, mode, &unsignedp);
1424 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1427 static rtx
1428 nds32_libcall_value (enum machine_mode mode,
1429 const_rtx fun ATTRIBUTE_UNUSED)
1431 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1434 static bool
1435 nds32_function_value_regno_p (const unsigned int regno)
1437 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1440 /* -- Function Entry and Exit. */
1442 /* The content produced from this function
1443 will be placed before prologue body. */
1444 static void
1445 nds32_asm_function_prologue (FILE *file,
1446 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1448 int r;
1449 const char *func_name;
1450 tree attrs;
1451 tree name;
1453 /* All stack frame information is supposed to be
1454 already computed when expanding prologue.
1455 The result is in cfun->machine.
1456 DO NOT call nds32_compute_stack_frame() here
1457 because it may corrupt the essential information. */
1459 fprintf (file, "\t! BEGIN PROLOGUE\n");
1460 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1461 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1462 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1463 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1465 /* Use df_regs_ever_live_p() to detect if the register
1466 is ever used in the current function. */
1467 fprintf (file, "\t! registers ever_live: ");
1468 for (r = 0; r < 32; r++)
1470 if (df_regs_ever_live_p (r))
1471 fprintf (file, "%s, ", reg_names[r]);
1473 fputc ('\n', file);
1475 /* Display the attributes of this function. */
1476 fprintf (file, "\t! function attributes: ");
1477 /* Get the attributes tree list.
1478 Note that GCC builds attributes list with reverse order. */
1479 attrs = DECL_ATTRIBUTES (current_function_decl);
1481 /* If there is no any attribute, print out "None". */
1482 if (!attrs)
1483 fprintf (file, "None");
1485 /* If there are some attributes, try if we need to
1486 construct isr vector information. */
1487 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1488 nds32_construct_isr_vectors_information (attrs, func_name);
1490 /* Display all attributes of this function. */
1491 while (attrs)
1493 name = TREE_PURPOSE (attrs);
1494 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1496 /* Pick up the next attribute. */
1497 attrs = TREE_CHAIN (attrs);
1499 fputc ('\n', file);
1502 /* After rtl prologue has been expanded, this function is used. */
1503 static void
1504 nds32_asm_function_end_prologue (FILE *file)
1506 fprintf (file, "\t! END PROLOGUE\n");
1508 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1509 we can generate special directive: ".omit_fp_begin"
1510 to guide linker doing fp-as-gp optimization.
1511 However, for a naked function, which means
1512 it should not have prologue/epilogue,
1513 using fp-as-gp still requires saving $fp by push/pop behavior and
1514 there is no benefit to use fp-as-gp on such small function.
1515 So we need to make sure this function is NOT naked as well. */
1516 if (!frame_pointer_needed
1517 && !cfun->machine->naked_p
1518 && cfun->machine->fp_as_gp_p)
1520 fprintf (file, "\t! ----------------------------------------\n");
1521 fprintf (file, "\t! Guide linker to do "
1522 "link time optimization: fp-as-gp\n");
1523 fprintf (file, "\t! We add one more instruction to "
1524 "initialize $fp near to $gp location.\n");
1525 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1526 fprintf (file, "\t! this extra instruction should be "
1527 "eliminated at link stage.\n");
1528 fprintf (file, "\t.omit_fp_begin\n");
1529 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1530 fprintf (file, "\t! ----------------------------------------\n");
1534 /* Before rtl epilogue has been expanded, this function is used. */
1535 static void
1536 nds32_asm_function_begin_epilogue (FILE *file)
1538 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1539 we can generate special directive: ".omit_fp_end"
1540 to claim fp-as-gp optimization range.
1541 However, for a naked function,
1542 which means it should not have prologue/epilogue,
1543 using fp-as-gp still requires saving $fp by push/pop behavior and
1544 there is no benefit to use fp-as-gp on such small function.
1545 So we need to make sure this function is NOT naked as well. */
1546 if (!frame_pointer_needed
1547 && !cfun->machine->naked_p
1548 && cfun->machine->fp_as_gp_p)
1550 fprintf (file, "\t! ----------------------------------------\n");
1551 fprintf (file, "\t! Claim the range of fp-as-gp "
1552 "link time optimization\n");
1553 fprintf (file, "\t.omit_fp_end\n");
1554 fprintf (file, "\t! ----------------------------------------\n");
1557 fprintf (file, "\t! BEGIN EPILOGUE\n");
1560 /* The content produced from this function
1561 will be placed after epilogue body. */
1562 static void
1563 nds32_asm_function_epilogue (FILE *file,
1564 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1566 fprintf (file, "\t! END EPILOGUE\n");
1569 static void
1570 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1571 HOST_WIDE_INT delta,
1572 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1573 tree function)
1575 int this_regno;
1577 /* Make sure unwind info is emitted for the thunk if needed. */
1578 final_start_function (emit_barrier (), file, 1);
1580 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1582 : 0);
1584 if (delta != 0)
1586 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1588 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1589 this_regno, this_regno, delta);
1591 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1593 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1594 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1596 else
1598 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1599 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1600 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1604 fprintf (file, "\tb\t");
1605 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1606 fprintf (file, "\n");
1608 final_end_function ();
1611 /* -- Permitting tail calls. */
1613 /* Determine whether we need to enable warning for function return check. */
1614 static bool
1615 nds32_warn_func_return (tree decl)
1617 /* Naked functions are implemented entirely in assembly, including the
1618 return sequence, so suppress warnings about this. */
1619 return !nds32_naked_function_p (decl);
1623 /* Implementing the Varargs Macros. */
1625 static void
1626 nds32_setup_incoming_varargs (cumulative_args_t ca,
1627 enum machine_mode mode,
1628 tree type,
1629 int *pretend_args_size,
1630 int second_time ATTRIBUTE_UNUSED)
1632 unsigned int total_args_regs;
1633 unsigned int num_of_used_regs;
1634 unsigned int remaining_reg_count;
1635 CUMULATIVE_ARGS *cum;
1637 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1638 So that all nameless arguments are pushed by caller and all situation
1639 can be handled by GCC itself. */
1640 if (TARGET_HARD_FLOAT)
1641 return;
1643 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1644 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1645 However, for nameless(anonymous) arguments, we should push them on the
1646 stack so that all the nameless arguments appear to have been passed
1647 consecutively in the memory for accessing. Hence, we need to check and
1648 exclude the registers that are used for named arguments. */
1650 cum = get_cumulative_args (ca);
1652 /* The MODE and TYPE describe the last argument.
1653 We need those information to determine the remaining registers
1654 for varargs. */
1655 total_args_regs
1656 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1657 num_of_used_regs
1658 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1659 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1661 remaining_reg_count = total_args_regs - num_of_used_regs;
1662 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1664 return;
1667 static bool
1668 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1670 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1671 true for named arguments, and false for unnamed arguments. */
1672 return true;
1676 /* Trampolines for Nested Functions. */
1678 static void
1679 nds32_asm_trampoline_template (FILE *f)
1681 if (TARGET_REDUCED_REGS)
1683 /* Trampoline is not supported on reduced-set registers yet. */
1684 sorry ("a nested function is not supported for reduced registers");
1686 else
1688 asm_fprintf (f, "\t! Trampoline code template\n");
1689 asm_fprintf (f, "\t! This code fragment will be copied "
1690 "into stack on demand\n");
1692 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1693 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1694 "! load nested function address\n");
1695 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1696 "! load chain_value\n");
1697 asm_fprintf (f, "\tjr\t$r15\n");
1700 /* Preserve space ($pc + 16) for saving chain_value,
1701 nds32_trampoline_init will fill the value in this slot. */
1702 asm_fprintf (f, "\t! space for saving chain_value\n");
1703 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1705 /* Preserve space ($pc + 20) for saving nested function address,
1706 nds32_trampoline_init will fill the value in this slot. */
1707 asm_fprintf (f, "\t! space for saving nested function address\n");
1708 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1711 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1712 static void
1713 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1715 int i;
1717 /* Nested function address. */
1718 rtx fnaddr;
1719 /* The memory rtx that is going to
1720 be filled with chain_value. */
1721 rtx chain_value_mem;
1722 /* The memory rtx that is going to
1723 be filled with nested function address. */
1724 rtx nested_func_mem;
1726 /* Start address of trampoline code in stack, for doing cache sync. */
1727 rtx sync_cache_addr;
1728 /* Temporary register for sync instruction. */
1729 rtx tmp_reg;
1730 /* Instruction-cache sync instruction,
1731 requesting an argument as starting address. */
1732 rtx isync_insn;
1733 /* For convenience reason of doing comparison. */
1734 int tramp_align_in_bytes;
1736 /* Trampoline is not supported on reduced-set registers yet. */
1737 if (TARGET_REDUCED_REGS)
1738 sorry ("a nested function is not supported for reduced registers");
1740 /* STEP 1: Copy trampoline code template into stack,
1741 fill up essential data into stack. */
1743 /* Extract nested function address rtx. */
1744 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1746 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1747 We have nds32_asm_trampoline_template() to emit template pattern. */
1748 emit_block_move (m_tramp, assemble_trampoline_template (),
1749 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1751 /* After copying trampoline code into stack,
1752 fill chain_value into stack. */
1753 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1754 emit_move_insn (chain_value_mem, chain_value);
1755 /* After copying trampoline code int stack,
1756 fill nested function address into stack. */
1757 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1758 emit_move_insn (nested_func_mem, fnaddr);
1760 /* STEP 2: Sync instruction-cache. */
1762 /* We have successfully filled trampoline code into stack.
1763 However, in order to execute code in stack correctly,
1764 we must sync instruction cache. */
1765 sync_cache_addr = XEXP (m_tramp, 0);
1766 tmp_reg = gen_reg_rtx (SImode);
1767 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1769 /* Because nds32_cache_block_size is in bytes,
1770 we get trampoline alignment in bytes for convenient comparison. */
1771 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1773 if (tramp_align_in_bytes >= nds32_cache_block_size
1774 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1776 /* Under this condition, the starting address of trampoline
1777 must be aligned to the starting address of each cache block
1778 and we do not have to worry about cross-boundary issue. */
1779 for (i = 0;
1780 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1781 / nds32_cache_block_size;
1782 i++)
1784 emit_move_insn (tmp_reg,
1785 plus_constant (Pmode, sync_cache_addr,
1786 nds32_cache_block_size * i));
1787 emit_insn (isync_insn);
1790 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1792 /* The starting address of trampoline code
1793 may not be aligned to the cache block,
1794 so the trampoline code may be across two cache block.
1795 We need to sync the last element, which is 4-byte size,
1796 of trampoline template. */
1797 for (i = 0;
1798 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1799 / nds32_cache_block_size;
1800 i++)
1802 emit_move_insn (tmp_reg,
1803 plus_constant (Pmode, sync_cache_addr,
1804 nds32_cache_block_size * i));
1805 emit_insn (isync_insn);
1808 /* The last element of trampoline template is 4-byte size. */
1809 emit_move_insn (tmp_reg,
1810 plus_constant (Pmode, sync_cache_addr,
1811 TRAMPOLINE_SIZE - 4));
1812 emit_insn (isync_insn);
1814 else
1816 /* This is the simplest case.
1817 Because TRAMPOLINE_SIZE is less than or
1818 equal to nds32_cache_block_size,
1819 we can just sync start address and
1820 the last element of trampoline code. */
1822 /* Sync starting address of tampoline code. */
1823 emit_move_insn (tmp_reg, sync_cache_addr);
1824 emit_insn (isync_insn);
1825 /* Sync the last element, which is 4-byte size,
1826 of trampoline template. */
1827 emit_move_insn (tmp_reg,
1828 plus_constant (Pmode, sync_cache_addr,
1829 TRAMPOLINE_SIZE - 4));
1830 emit_insn (isync_insn);
1833 /* Set instruction serialization barrier
1834 to guarantee the correct operations. */
1835 emit_insn (gen_unspec_volatile_isb ());
1839 /* Addressing Modes. */
1841 static bool
1842 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1844 /* For (mem:DI addr) or (mem:DF addr) case,
1845 we only allow 'addr' to be [reg], [symbol_ref],
1846 [const], or [reg + const_int] pattern. */
1847 if (mode == DImode || mode == DFmode)
1849 /* Allow [Reg + const_int] addressing mode. */
1850 if (GET_CODE (x) == PLUS)
1852 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1853 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1854 && CONST_INT_P (XEXP (x, 1)))
1855 return true;
1857 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1858 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1859 && CONST_INT_P (XEXP (x, 0)))
1860 return true;
1863 /* Now check [reg], [symbol_ref], and [const]. */
1864 if (GET_CODE (x) != REG
1865 && GET_CODE (x) != SYMBOL_REF
1866 && GET_CODE (x) != CONST)
1867 return false;
1870 /* Check if 'x' is a valid address. */
1871 switch (GET_CODE (x))
1873 case REG:
1874 /* (mem (reg A)) => [Ra] */
1875 return nds32_address_register_rtx_p (x, strict);
1877 case SYMBOL_REF:
1879 if (!TARGET_GP_DIRECT
1880 && (reload_completed
1881 || reload_in_progress
1882 || lra_in_progress))
1883 return false;
1885 /* (mem (symbol_ref A)) => [symbol_ref] */
1886 return !currently_expanding_to_rtl;
1888 case CONST:
1890 if (!TARGET_GP_DIRECT
1891 && (reload_completed
1892 || reload_in_progress
1893 || lra_in_progress))
1894 return false;
1896 /* (mem (const (...)))
1897 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1898 if (GET_CODE (XEXP (x, 0)) == PLUS)
1900 rtx plus_op = XEXP (x, 0);
1902 rtx op0 = XEXP (plus_op, 0);
1903 rtx op1 = XEXP (plus_op, 1);
1905 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1906 return true;
1907 else
1908 return false;
1911 return false;
1913 case POST_MODIFY:
1914 /* (mem (post_modify (reg) (plus (reg) (reg))))
1915 => [Ra], Rb */
1916 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1917 => [Ra], const_int */
1918 if (GET_CODE (XEXP (x, 0)) == REG
1919 && GET_CODE (XEXP (x, 1)) == PLUS)
1921 rtx plus_op = XEXP (x, 1);
1923 rtx op0 = XEXP (plus_op, 0);
1924 rtx op1 = XEXP (plus_op, 1);
1926 if (nds32_address_register_rtx_p (op0, strict)
1927 && nds32_legitimate_index_p (mode, op1, strict))
1928 return true;
1929 else
1930 return false;
1933 return false;
1935 case POST_INC:
1936 case POST_DEC:
1937 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
1938 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
1939 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
1940 We only need to deal with register Ra. */
1941 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
1942 return true;
1943 else
1944 return false;
1946 case PLUS:
1947 /* (mem (plus reg const_int))
1948 => [Ra + imm] */
1949 /* (mem (plus reg reg))
1950 => [Ra + Rb] */
1951 /* (mem (plus (mult reg const_int) reg))
1952 => [Ra + Rb << sv] */
1953 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1954 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
1955 return true;
1956 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1957 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
1958 return true;
1959 else
1960 return false;
1962 case LO_SUM:
1963 if (!TARGET_GP_DIRECT)
1964 return true;
1966 default:
1967 return false;
1972 /* Describing Relative Costs of Operations. */
1974 static int
1975 nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1976 reg_class_t from,
1977 reg_class_t to)
1979 if (from == HIGH_REGS || to == HIGH_REGS)
1980 return 6;
1982 return 2;
1985 static int
1986 nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1987 reg_class_t rclass ATTRIBUTE_UNUSED,
1988 bool in ATTRIBUTE_UNUSED)
1990 return 8;
1993 /* This target hook describes the relative costs of RTL expressions.
1994 Return 'true' when all subexpressions of x have been processed.
1995 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
1996 Refer to gcc/rtlanal.c for more information. */
1997 static bool
1998 nds32_rtx_costs (rtx x,
1999 int code,
2000 int outer_code,
2001 int opno,
2002 int *total,
2003 bool speed)
2005 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
2008 static int
2009 nds32_address_cost (rtx address,
2010 enum machine_mode mode,
2011 addr_space_t as,
2012 bool speed)
2014 return nds32_address_cost_impl (address, mode, as, speed);
2018 /* Defining the Output Assembler Language. */
2020 /* -- The Overall Framework of an Assembler File. */
2022 static void
2023 nds32_asm_file_start (void)
2025 default_file_start ();
2027 /* Tell assembler which ABI we are using. */
2028 fprintf (asm_out_file, "\t! ABI version\n");
2029 fprintf (asm_out_file, "\t.abi_2\n");
2031 /* Tell assembler that this asm code is generated by compiler. */
2032 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2033 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2034 /* Give assembler the size of each vector for interrupt handler. */
2035 fprintf (asm_out_file, "\t! This vector size directive is required "
2036 "for checking inconsistency on interrupt handler\n");
2037 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2039 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2040 the compiler may produce 'la $fp,_FP_BASE_' instruction
2041 at prologue for fp-as-gp optimization.
2042 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2043 in case user does not pass '--relax' option to linker. */
2044 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2046 fprintf (asm_out_file, "\t! This weak reference is required to do "
2047 "fp-as-gp link time optimization\n");
2048 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2050 /* If user enables '-mex9', we should emit relaxation directive
2051 to tell linker that this file is allowed to do ex9 optimization. */
2052 if (TARGET_EX9)
2054 fprintf (asm_out_file, "\t! This relaxation directive is required "
2055 "to do ex9 link time optimization\n");
2056 fprintf (asm_out_file, "\t.relax\tex9\n");
2059 fprintf (asm_out_file, "\t! ------------------------------------\n");
2061 if (TARGET_ISA_V2)
2062 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2063 if (TARGET_ISA_V3)
2064 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2065 if (TARGET_ISA_V3M)
2066 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2068 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2069 ((TARGET_BIG_ENDIAN) ? "big-endian"
2070 : "little-endian"));
2072 fprintf (asm_out_file, "\t! ------------------------------------\n");
2074 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2075 ((TARGET_CMOV) ? "Yes"
2076 : "No"));
2077 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2078 ((TARGET_PERF_EXT) ? "Yes"
2079 : "No"));
2081 fprintf (asm_out_file, "\t! ------------------------------------\n");
2083 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2084 ((TARGET_V3PUSH) ? "Yes"
2085 : "No"));
2086 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2087 ((TARGET_16_BIT) ? "Yes"
2088 : "No"));
2089 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2090 ((TARGET_GP_DIRECT) ? "Yes"
2091 : "No"));
2092 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2093 ((TARGET_REDUCED_REGS) ? "Yes"
2094 : "No"));
2096 fprintf (asm_out_file, "\t! ------------------------------------\n");
2098 if (optimize_size)
2099 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2100 else
2101 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2103 fprintf (asm_out_file, "\t! ------------------------------------\n");
2105 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2106 nds32_cache_block_size);
2108 fprintf (asm_out_file, "\t! ------------------------------------\n");
2110 nds32_asm_file_start_for_isr ();
2113 static void
2114 nds32_asm_file_end (void)
2116 nds32_asm_file_end_for_isr ();
2118 fprintf (asm_out_file, "\t! ------------------------------------\n");
2121 /* -- Output and Generation of Labels. */
2123 static void
2124 nds32_asm_globalize_label (FILE *stream, const char *name)
2126 fputs ("\t.global\t", stream);
2127 assemble_name (stream, name);
2128 fputs ("\n", stream);
2131 /* -- Output of Assembler Instructions. */
2133 static void
2134 nds32_print_operand (FILE *stream, rtx x, int code)
2136 int op_value;
2138 switch (code)
2140 case 0 :
2141 /* Do nothing special. */
2142 break;
2144 case 'V':
2145 /* 'x' is supposed to be CONST_INT, get the value. */
2146 gcc_assert (CONST_INT_P (x));
2147 op_value = INTVAL (x);
2149 /* According to the Andes architecture,
2150 the system/user register index range is 0 ~ 1023.
2151 In order to avoid conflict between user-specified-integer value
2152 and enum-specified-register value,
2153 the 'enum nds32_intrinsic_registers' value
2154 in nds32_intrinsic.h starts from 1024. */
2155 if (op_value < 1024 && op_value >= 0)
2157 /* If user gives integer value directly (0~1023),
2158 we just print out the value. */
2159 fprintf (stream, "%d", op_value);
2161 else if (op_value < 0
2162 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2163 + 1024))
2165 /* The enum index value for array size is out of range. */
2166 error ("intrinsic register index is out of range");
2168 else
2170 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2171 we can print out register name. Remember to substract 1024. */
2172 fprintf (stream, "%s",
2173 nds32_intrinsic_register_names[op_value - 1024]);
2176 /* No need to handle following process, so return immediately. */
2177 return;
2179 default :
2180 /* Unknown flag. */
2181 output_operand_lossage ("invalid operand output code");
2182 break;
2185 switch (GET_CODE (x))
2187 case LABEL_REF:
2188 case SYMBOL_REF:
2189 output_addr_const (stream, x);
2190 break;
2192 case REG:
2193 /* Forbid using static chain register ($r16)
2194 on reduced-set registers configuration. */
2195 if (TARGET_REDUCED_REGS
2196 && REGNO (x) == STATIC_CHAIN_REGNUM)
2197 sorry ("a nested function is not supported for reduced registers");
2199 /* Normal cases, print out register name. */
2200 fputs (reg_names[REGNO (x)], stream);
2201 break;
2203 case MEM:
2204 output_address (XEXP (x, 0));
2205 break;
2207 case CODE_LABEL:
2208 case CONST_INT:
2209 case CONST:
2210 output_addr_const (stream, x);
2211 break;
2213 default:
2214 /* Generally, output_addr_const () is able to handle most cases.
2215 We want to see what CODE could appear,
2216 so we use gcc_unreachable() to stop it. */
2217 debug_rtx (x);
2218 gcc_unreachable ();
2219 break;
2223 static void
2224 nds32_print_operand_address (FILE *stream, rtx x)
2226 rtx op0, op1;
2228 switch (GET_CODE (x))
2230 case SYMBOL_REF:
2231 case CONST:
2232 /* [ + symbol_ref] */
2233 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2234 fputs ("[ + ", stream);
2235 output_addr_const (stream, x);
2236 fputs ("]", stream);
2237 break;
2239 case REG:
2240 /* Forbid using static chain register ($r16)
2241 on reduced-set registers configuration. */
2242 if (TARGET_REDUCED_REGS
2243 && REGNO (x) == STATIC_CHAIN_REGNUM)
2244 sorry ("a nested function is not supported for reduced registers");
2246 /* [Ra] */
2247 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2248 break;
2250 case PLUS:
2251 op0 = XEXP (x, 0);
2252 op1 = XEXP (x, 1);
2254 /* Checking op0, forbid using static chain register ($r16)
2255 on reduced-set registers configuration. */
2256 if (TARGET_REDUCED_REGS
2257 && REG_P (op0)
2258 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2259 sorry ("a nested function is not supported for reduced registers");
2260 /* Checking op1, forbid using static chain register ($r16)
2261 on reduced-set registers configuration. */
2262 if (TARGET_REDUCED_REGS
2263 && REG_P (op1)
2264 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2265 sorry ("a nested function is not supported for reduced registers");
2267 if (REG_P (op0) && CONST_INT_P (op1))
2269 /* [Ra + imm] */
2270 fprintf (stream, "[%s + (%d)]",
2271 reg_names[REGNO (op0)], (int)INTVAL (op1));
2273 else if (REG_P (op0) && REG_P (op1))
2275 /* [Ra + Rb] */
2276 fprintf (stream, "[%s + %s]",
2277 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2279 else if (GET_CODE (op0) == MULT && REG_P (op1))
2281 /* [Ra + Rb << sv]
2282 From observation, the pattern looks like:
2283 (plus:SI (mult:SI (reg:SI 58)
2284 (const_int 4 [0x4]))
2285 (reg/f:SI 57)) */
2286 int sv;
2288 /* We need to set sv to output shift value. */
2289 if (INTVAL (XEXP (op0, 1)) == 1)
2290 sv = 0;
2291 else if (INTVAL (XEXP (op0, 1)) == 2)
2292 sv = 1;
2293 else if (INTVAL (XEXP (op0, 1)) == 4)
2294 sv = 2;
2295 else
2296 gcc_unreachable ();
2298 fprintf (stream, "[%s + %s << %d]",
2299 reg_names[REGNO (op1)],
2300 reg_names[REGNO (XEXP (op0, 0))],
2301 sv);
2303 else
2305 /* The control flow is not supposed to be here. */
2306 debug_rtx (x);
2307 gcc_unreachable ();
2310 break;
2312 case POST_MODIFY:
2313 /* (post_modify (regA) (plus (regA) (regB)))
2314 (post_modify (regA) (plus (regA) (const_int)))
2315 We would like to extract
2316 regA and regB (or const_int) from plus rtx. */
2317 op0 = XEXP (XEXP (x, 1), 0);
2318 op1 = XEXP (XEXP (x, 1), 1);
2320 /* Checking op0, forbid using static chain register ($r16)
2321 on reduced-set registers configuration. */
2322 if (TARGET_REDUCED_REGS
2323 && REG_P (op0)
2324 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2325 sorry ("a nested function is not supported for reduced registers");
2326 /* Checking op1, forbid using static chain register ($r16)
2327 on reduced-set registers configuration. */
2328 if (TARGET_REDUCED_REGS
2329 && REG_P (op1)
2330 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2331 sorry ("a nested function is not supported for reduced registers");
2333 if (REG_P (op0) && REG_P (op1))
2335 /* [Ra], Rb */
2336 fprintf (stream, "[%s], %s",
2337 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2339 else if (REG_P (op0) && CONST_INT_P (op1))
2341 /* [Ra], imm */
2342 fprintf (stream, "[%s], %d",
2343 reg_names[REGNO (op0)], (int)INTVAL (op1));
2345 else
2347 /* The control flow is not supposed to be here. */
2348 debug_rtx (x);
2349 gcc_unreachable ();
2352 break;
2354 case POST_INC:
2355 case POST_DEC:
2356 op0 = XEXP (x, 0);
2358 /* Checking op0, forbid using static chain register ($r16)
2359 on reduced-set registers configuration. */
2360 if (TARGET_REDUCED_REGS
2361 && REG_P (op0)
2362 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2363 sorry ("a nested function is not supported for reduced registers");
2365 if (REG_P (op0))
2367 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2368 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2369 We only need to deal with register Ra. */
2370 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2372 else
2374 /* The control flow is not supposed to be here. */
2375 debug_rtx (x);
2376 gcc_unreachable ();
2379 break;
2381 default :
2382 /* Generally, output_addr_const () is able to handle most cases.
2383 We want to see what CODE could appear,
2384 so we use gcc_unreachable() to stop it. */
2385 debug_rtx (x);
2386 gcc_unreachable ();
2387 break;
2392 /* Defining target-specific uses of __attribute__. */
2394 /* Add some checking after merging attributes. */
2395 static tree
2396 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2398 tree combined_attrs;
2400 /* Create combined attributes. */
2401 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2402 DECL_ATTRIBUTES (newdecl));
2404 /* Since newdecl is acutally a duplicate of olddecl,
2405 we can take olddecl for some operations. */
2406 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2408 /* Check isr-specific attributes conflict. */
2409 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2412 return combined_attrs;
2415 /* Add some checking when inserting attributes. */
2416 static void
2417 nds32_insert_attributes (tree decl, tree *attributes)
2419 /* For function declaration, we need to check isr-specific attributes:
2420 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2421 2. Check valid integer value for interrupt/exception.
2422 3. Check valid integer value for reset.
2423 4. Check valid function for nmi/warm. */
2424 if (TREE_CODE (decl) == FUNCTION_DECL)
2426 tree func_attrs;
2427 tree intr, excp, reset;
2429 /* Pick up function attributes. */
2430 func_attrs = *attributes;
2432 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2433 nds32_check_isr_attrs_conflict (decl, func_attrs);
2435 /* Now we are starting to check valid id value
2436 for interrupt/exception/reset.
2437 Note that we ONLY check its validity here.
2438 To construct isr vector information, it is still performed
2439 by nds32_construct_isr_vectors_information(). */
2440 intr = lookup_attribute ("interrupt", func_attrs);
2441 excp = lookup_attribute ("exception", func_attrs);
2442 reset = lookup_attribute ("reset", func_attrs);
2444 if (intr || excp)
2446 /* Deal with interrupt/exception. */
2447 tree id_list;
2448 unsigned int lower_bound, upper_bound;
2450 /* The way to handle interrupt or exception is the same,
2451 we just need to take care of actual vector number.
2452 For interrupt(0..63), the actual vector number is (9..72).
2453 For exception(1..8), the actual vector number is (1..8). */
2454 lower_bound = (intr) ? (0) : (1);
2455 upper_bound = (intr) ? (63) : (8);
2457 /* Prepare id list so that we can traverse id value. */
2458 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2460 /* 2. Check valid integer value for interrupt/exception. */
2461 while (id_list)
2463 tree id;
2465 /* Pick up each vector id value. */
2466 id = TREE_VALUE (id_list);
2467 /* Issue error if it is not a valid integer value. */
2468 if (TREE_CODE (id) != INTEGER_CST
2469 || wi::ltu_p (id, lower_bound)
2470 || wi::gtu_p (id, upper_bound))
2471 error ("invalid id value for interrupt/exception attribute");
2473 /* Advance to next id. */
2474 id_list = TREE_CHAIN (id_list);
2477 else if (reset)
2479 /* Deal with reset. */
2480 tree id_list;
2481 tree id;
2482 tree nmi, warm;
2483 unsigned int lower_bound;
2484 unsigned int upper_bound;
2486 /* Prepare id_list and identify id value so that
2487 we can check if total number of vectors is valid. */
2488 id_list = TREE_VALUE (reset);
2489 id = TREE_VALUE (id_list);
2491 /* The maximum numbers for user's interrupt is 64. */
2492 lower_bound = 0;
2493 upper_bound = 64;
2495 /* 3. Check valid integer value for reset. */
2496 if (TREE_CODE (id) != INTEGER_CST
2497 || wi::ltu_p (id, lower_bound)
2498 || wi::gtu_p (id, upper_bound))
2499 error ("invalid id value for reset attribute");
2501 /* 4. Check valid function for nmi/warm. */
2502 nmi = lookup_attribute ("nmi", func_attrs);
2503 warm = lookup_attribute ("warm", func_attrs);
2505 if (nmi != NULL_TREE)
2507 tree nmi_func_list;
2508 tree nmi_func;
2510 nmi_func_list = TREE_VALUE (nmi);
2511 nmi_func = TREE_VALUE (nmi_func_list);
2513 /* Issue error if it is not a valid nmi function. */
2514 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2515 error ("invalid nmi function for reset attribute");
2518 if (warm != NULL_TREE)
2520 tree warm_func_list;
2521 tree warm_func;
2523 warm_func_list = TREE_VALUE (warm);
2524 warm_func = TREE_VALUE (warm_func_list);
2526 /* Issue error if it is not a valid warm function. */
2527 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2528 error ("invalid warm function for reset attribute");
2531 else
2533 /* No interrupt, exception, or reset attribute is set. */
2534 return;
2539 static bool
2540 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2541 tree pop_target ATTRIBUTE_UNUSED)
2543 /* Currently, we do not parse any pragma target by ourself,
2544 so just simply return false. */
2545 return false;
2548 static void
2549 nds32_option_override (void)
2551 /* After all the command options have been parsed,
2552 we shall deal with some flags for changing compiler settings. */
2554 /* At first, we check if we have to strictly
2555 set some flags based on ISA family. */
2556 if (TARGET_ISA_V2)
2558 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2559 target_flags &= ~MASK_V3PUSH;
2561 if (TARGET_ISA_V3)
2563 /* Under V3 ISA, currently nothing should be strictly set. */
2565 if (TARGET_ISA_V3M)
2567 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2568 target_flags |= MASK_REDUCED_REGS;
2569 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2570 target_flags &= ~MASK_PERF_EXT;
2573 /* See if we are using reduced-set registers:
2574 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2575 If so, we must forbid using $r11~$r14, $r16~$r27. */
2576 if (TARGET_REDUCED_REGS)
2578 int r;
2580 /* Prevent register allocator from
2581 choosing it as doing register allocation. */
2582 for (r = 11; r <= 14; r++)
2583 fixed_regs[r] = call_used_regs[r] = 1;
2584 for (r = 16; r <= 27; r++)
2585 fixed_regs[r] = call_used_regs[r] = 1;
2588 /* See if user explicitly would like to use fp-as-gp optimization.
2589 If so, we must prevent $fp from being allocated
2590 during register allocation. */
2591 if (TARGET_FORCE_FP_AS_GP)
2592 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2594 if (!TARGET_16_BIT)
2596 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2597 target_flags &= ~MASK_V3PUSH;
2600 /* Currently, we don't support PIC code generation yet. */
2601 if (flag_pic)
2602 sorry ("not support -fpic");
2606 /* Miscellaneous Parameters. */
2608 static void
2609 nds32_init_builtins (void)
2611 nds32_init_builtins_impl ();
2614 static rtx
2615 nds32_expand_builtin (tree exp,
2616 rtx target,
2617 rtx subtarget,
2618 enum machine_mode mode,
2619 int ignore)
2621 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2625 /* ------------------------------------------------------------------------ */
2627 /* PART 4: Implemet extern function definitions,
2628 the prototype is in nds32-protos.h. */
2630 /* Defining Data Structures for Per-function Information. */
2632 void
2633 nds32_init_expanders (void)
2635 /* Arrange to initialize and mark the machine per-function status. */
2636 init_machine_status = nds32_init_machine_status;
2640 /* Register Usage. */
2642 /* -- How Values Fit in Registers. */
2645 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2646 enum machine_mode mode)
2648 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2652 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
2654 /* Restrict double-word quantities to even register pairs. */
2655 if (HARD_REGNO_NREGS (regno, mode) == 1
2656 || !((regno) & 1))
2657 return 1;
2659 return 0;
2663 /* Register Classes. */
2665 enum reg_class
2666 nds32_regno_reg_class (int regno)
2668 /* Refer to nds32.h for more register class details. */
2670 if (regno >= 0 && regno <= 7)
2671 return LOW_REGS;
2672 else if (regno >= 8 && regno <= 11)
2673 return MIDDLE_REGS;
2674 else if (regno >= 12 && regno <= 14)
2675 return HIGH_REGS;
2676 else if (regno == 15)
2677 return R15_TA_REG;
2678 else if (regno >= 16 && regno <= 19)
2679 return MIDDLE_REGS;
2680 else if (regno >= 20 && regno <= 31)
2681 return HIGH_REGS;
2682 else if (regno == 32 || regno == 33)
2683 return FRAME_REGS;
2684 else
2685 return NO_REGS;
2689 /* Stack Layout and Calling Conventions. */
2691 /* -- Basic Stack Layout. */
2694 nds32_return_addr_rtx (int count,
2695 rtx frameaddr ATTRIBUTE_UNUSED)
2697 /* There is no way to determine the return address
2698 if frameaddr is the frame that has 'count' steps
2699 up from current frame. */
2700 if (count != 0)
2701 return NULL_RTX;
2703 /* If count == 0, it means we are at current frame,
2704 the return address is $r30 ($lp). */
2705 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2708 /* -- Eliminating Frame Pointer and Arg Pointer. */
2710 HOST_WIDE_INT
2711 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2713 HOST_WIDE_INT offset;
2715 /* Compute and setup stack frame size.
2716 The result will be in cfun->machine. */
2717 nds32_compute_stack_frame ();
2719 /* Remember to consider
2720 cfun->machine->callee_saved_area_padding_bytes
2721 when calculating offset. */
2722 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2724 offset = (cfun->machine->fp_size
2725 + cfun->machine->gp_size
2726 + cfun->machine->lp_size
2727 + cfun->machine->callee_saved_regs_size
2728 + cfun->machine->callee_saved_area_padding_bytes
2729 + cfun->machine->local_size
2730 + cfun->machine->out_args_size);
2732 else if (from_reg == ARG_POINTER_REGNUM
2733 && to_reg == HARD_FRAME_POINTER_REGNUM)
2735 offset = 0;
2737 else if (from_reg == FRAME_POINTER_REGNUM
2738 && to_reg == STACK_POINTER_REGNUM)
2740 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2742 else if (from_reg == FRAME_POINTER_REGNUM
2743 && to_reg == HARD_FRAME_POINTER_REGNUM)
2745 offset = (-1) * (cfun->machine->fp_size
2746 + cfun->machine->gp_size
2747 + cfun->machine->lp_size
2748 + cfun->machine->callee_saved_regs_size
2749 + cfun->machine->callee_saved_area_padding_bytes);
2751 else
2753 gcc_unreachable ();
2756 return offset;
2759 /* -- Passing Arguments in Registers. */
2761 void
2762 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2763 tree fntype ATTRIBUTE_UNUSED,
2764 rtx libname ATTRIBUTE_UNUSED,
2765 tree fndecl ATTRIBUTE_UNUSED,
2766 int n_named_args ATTRIBUTE_UNUSED)
2768 /* Initial available registers
2769 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2770 for passing arguments. */
2771 cum->gpr_offset = 0;
2774 /* -- Function Entry and Exit. */
2776 /* Function for normal multiple push prologue. */
2777 void
2778 nds32_expand_prologue (void)
2780 int fp_adjust;
2781 int sp_adjust;
2782 int en4_const;
2784 rtx Rb, Re;
2785 rtx fp_adjust_insn, sp_adjust_insn;
2787 /* Before computing everything for stack frame size,
2788 we check if it is still worth to use fp_as_gp optimization.
2789 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2790 so that $fp will be saved on stack. */
2791 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
2793 /* Compute and setup stack frame size.
2794 The result will be in cfun->machine. */
2795 nds32_compute_stack_frame ();
2797 /* If the function is 'naked',
2798 we do not have to generate prologue code fragment. */
2799 if (cfun->machine->naked_p)
2800 return;
2802 /* Get callee_first_regno and callee_last_regno. */
2803 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2804 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2806 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2807 the pattern 'stack_push_multiple' is implemented in nds32.md.
2808 For En4 field, we have to calculate its constant value.
2809 Refer to Andes ISA for more information. */
2810 en4_const = 0;
2811 if (cfun->machine->fp_size)
2812 en4_const += 8;
2813 if (cfun->machine->gp_size)
2814 en4_const += 4;
2815 if (cfun->machine->lp_size)
2816 en4_const += 2;
2818 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2819 to be saved, we don't have to create multiple push instruction.
2820 Otherwise, a multiple push instruction is needed. */
2821 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2823 /* Create multiple push instruction rtx. */
2824 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
2827 /* Check frame_pointer_needed to see
2828 if we shall emit fp adjustment instruction. */
2829 if (frame_pointer_needed)
2831 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2832 + (4 * callee-saved-registers)
2833 Note: No need to adjust
2834 cfun->machine->callee_saved_area_padding_bytes,
2835 because, at this point, stack pointer is just
2836 at the position after push instruction. */
2837 fp_adjust = cfun->machine->fp_size
2838 + cfun->machine->gp_size
2839 + cfun->machine->lp_size
2840 + cfun->machine->callee_saved_regs_size;
2841 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2842 stack_pointer_rtx,
2843 GEN_INT (fp_adjust));
2844 /* Emit rtx into instructions list and receive INSN rtx form. */
2845 fp_adjust_insn = emit_insn (fp_adjust_insn);
2848 /* Adjust $sp = $sp - local_size - out_args_size
2849 - callee_saved_area_padding_bytes. */
2850 sp_adjust = cfun->machine->local_size
2851 + cfun->machine->out_args_size
2852 + cfun->machine->callee_saved_area_padding_bytes;
2853 /* sp_adjust value may be out of range of the addi instruction,
2854 create alternative add behavior with TA_REGNUM if necessary,
2855 using NEGATIVE value to tell that we are decreasing address. */
2856 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2857 if (sp_adjust)
2859 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2860 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2861 stack_pointer_rtx,
2862 GEN_INT (-1 * sp_adjust));
2863 /* Emit rtx into instructions list and receive INSN rtx form. */
2864 sp_adjust_insn = emit_insn (sp_adjust_insn);
2866 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2867 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2868 generate CFI (Call Frame Information) stuff. */
2869 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2872 /* Prevent the instruction scheduler from
2873 moving instructions across the boundary. */
2874 emit_insn (gen_blockage ());
2877 /* Function for normal multiple pop epilogue. */
2878 void
2879 nds32_expand_epilogue (void)
2881 int sp_adjust;
2882 int en4_const;
2884 rtx Rb, Re;
2885 rtx sp_adjust_insn;
2887 /* Compute and setup stack frame size.
2888 The result will be in cfun->machine. */
2889 nds32_compute_stack_frame ();
2891 /* Prevent the instruction scheduler from
2892 moving instructions across the boundary. */
2893 emit_insn (gen_blockage ());
2895 /* If the function is 'naked', we do not have to generate
2896 epilogue code fragment BUT 'ret' instruction. */
2897 if (cfun->machine->naked_p)
2899 /* Generate return instruction by using
2900 unspec_volatile_func_return pattern.
2901 Make sure this instruction is after gen_blockage().
2902 NOTE that $lp will become 'live'
2903 after this instruction has been emitted. */
2904 emit_insn (gen_unspec_volatile_func_return ());
2905 return;
2908 if (frame_pointer_needed)
2910 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
2911 - (4 * callee-saved-registers)
2912 Note: No need to adjust
2913 cfun->machine->callee_saved_area_padding_bytes,
2914 because we want to adjust stack pointer
2915 to the position for pop instruction. */
2916 sp_adjust = cfun->machine->fp_size
2917 + cfun->machine->gp_size
2918 + cfun->machine->lp_size
2919 + cfun->machine->callee_saved_regs_size;
2920 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2921 hard_frame_pointer_rtx,
2922 GEN_INT (-1 * sp_adjust));
2923 /* Emit rtx into instructions list and receive INSN rtx form. */
2924 sp_adjust_insn = emit_insn (sp_adjust_insn);
2926 else
2928 /* If frame pointer is NOT needed,
2929 we cannot calculate the sp adjustment from frame pointer.
2930 Instead, we calculate the adjustment by local_size,
2931 out_args_size, and callee_saved_area_padding_bytes.
2932 Notice that such sp adjustment value may be out of range,
2933 so we have to deal with it as well. */
2935 /* Adjust $sp = $sp + local_size + out_args_size
2936 + callee_saved_area_padding_bytes. */
2937 sp_adjust = cfun->machine->local_size
2938 + cfun->machine->out_args_size
2939 + cfun->machine->callee_saved_area_padding_bytes;
2940 /* sp_adjust value may be out of range of the addi instruction,
2941 create alternative add behavior with TA_REGNUM if necessary,
2942 using POSITIVE value to tell that we are increasing address. */
2943 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
2944 if (sp_adjust)
2946 /* Generate sp adjustment instruction
2947 if and only if sp_adjust != 0. */
2948 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2949 stack_pointer_rtx,
2950 GEN_INT (sp_adjust));
2951 /* Emit rtx into instructions list and receive INSN rtx form. */
2952 sp_adjust_insn = emit_insn (sp_adjust_insn);
2956 /* Get callee_first_regno and callee_last_regno. */
2957 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2958 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2960 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
2961 the pattern 'stack_pop_multiple' is implementad in nds32.md.
2962 For En4 field, we have to calculate its constant value.
2963 Refer to Andes ISA for more information. */
2964 en4_const = 0;
2965 if (cfun->machine->fp_size)
2966 en4_const += 8;
2967 if (cfun->machine->gp_size)
2968 en4_const += 4;
2969 if (cfun->machine->lp_size)
2970 en4_const += 2;
2972 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2973 to be saved, we don't have to create multiple pop instruction.
2974 Otherwise, a multiple pop instruction is needed. */
2975 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2977 /* Create multiple pop instruction rtx. */
2978 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
2981 /* Generate return instruction by using
2982 unspec_volatile_func_return pattern. */
2983 emit_insn (gen_unspec_volatile_func_return ());
2986 /* Function for v3push prologue. */
2987 void
2988 nds32_expand_prologue_v3push (void)
2990 int fp_adjust;
2991 int sp_adjust;
2993 rtx Rb, Re;
2994 rtx fp_adjust_insn, sp_adjust_insn;
2996 /* Before computing everything for stack frame size,
2997 we check if it is still worth to use fp_as_gp optimization.
2998 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2999 so that $fp will be saved on stack. */
3000 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
3002 /* Compute and setup stack frame size.
3003 The result will be in cfun->machine. */
3004 nds32_compute_stack_frame ();
3006 /* If the function is 'naked',
3007 we do not have to generate prologue code fragment. */
3008 if (cfun->machine->naked_p)
3009 return;
3011 /* Get callee_first_regno and callee_last_regno. */
3012 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3013 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3015 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3016 where imm8u has to be 8-byte alignment. */
3017 sp_adjust = cfun->machine->local_size
3018 + cfun->machine->out_args_size
3019 + cfun->machine->callee_saved_area_padding_bytes;
3021 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3022 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3024 /* We can use 'push25 Re,imm8u'. */
3026 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3027 the pattern 'stack_v3push' is implemented in nds32.md.
3028 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3029 nds32_emit_stack_v3push (Rb, Re,
3030 GEN_INT (14), GEN_INT (sp_adjust));
3032 /* Check frame_pointer_needed to see
3033 if we shall emit fp adjustment instruction. */
3034 if (frame_pointer_needed)
3036 /* adjust $fp = $sp + 4 ($fp size)
3037 + 4 ($gp size)
3038 + 4 ($lp size)
3039 + (4 * n) (callee-saved registers)
3040 + sp_adjust ('push25 Re,imm8u')
3041 Note: Since we use 'push25 Re,imm8u',
3042 the position of stack pointer is further
3043 changed after push instruction.
3044 Hence, we need to take sp_adjust value
3045 into consideration. */
3046 fp_adjust = cfun->machine->fp_size
3047 + cfun->machine->gp_size
3048 + cfun->machine->lp_size
3049 + cfun->machine->callee_saved_regs_size
3050 + sp_adjust;
3051 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3052 stack_pointer_rtx,
3053 GEN_INT (fp_adjust));
3054 /* Emit rtx into instructions list and receive INSN rtx form. */
3055 fp_adjust_insn = emit_insn (fp_adjust_insn);
3058 else
3060 /* We have to use 'push25 Re,0' and
3061 expand one more instruction to adjust $sp later. */
3063 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3064 the pattern 'stack_v3push' is implemented in nds32.md.
3065 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3066 nds32_emit_stack_v3push (Rb, Re,
3067 GEN_INT (14), GEN_INT (0));
3069 /* Check frame_pointer_needed to see
3070 if we shall emit fp adjustment instruction. */
3071 if (frame_pointer_needed)
3073 /* adjust $fp = $sp + 4 ($fp size)
3074 + 4 ($gp size)
3075 + 4 ($lp size)
3076 + (4 * n) (callee-saved registers)
3077 Note: Since we use 'push25 Re,0',
3078 the stack pointer is just at the position
3079 after push instruction.
3080 No need to take sp_adjust into consideration. */
3081 fp_adjust = cfun->machine->fp_size
3082 + cfun->machine->gp_size
3083 + cfun->machine->lp_size
3084 + cfun->machine->callee_saved_regs_size;
3085 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3086 stack_pointer_rtx,
3087 GEN_INT (fp_adjust));
3088 /* Emit rtx into instructions list and receive INSN rtx form. */
3089 fp_adjust_insn = emit_insn (fp_adjust_insn);
3092 /* Because we use 'push25 Re,0',
3093 we need to expand one more instruction to adjust $sp.
3094 However, sp_adjust value may be out of range of the addi instruction,
3095 create alternative add behavior with TA_REGNUM if necessary,
3096 using NEGATIVE value to tell that we are decreasing address. */
3097 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3098 if (sp_adjust)
3100 /* Generate sp adjustment instruction
3101 if and only if sp_adjust != 0. */
3102 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3103 stack_pointer_rtx,
3104 GEN_INT (-1 * sp_adjust));
3105 /* Emit rtx into instructions list and receive INSN rtx form. */
3106 sp_adjust_insn = emit_insn (sp_adjust_insn);
3108 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3109 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3110 generate CFI (Call Frame Information) stuff. */
3111 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3115 /* Prevent the instruction scheduler from
3116 moving instructions across the boundary. */
3117 emit_insn (gen_blockage ());
3120 /* Function for v3pop epilogue. */
3121 void
3122 nds32_expand_epilogue_v3pop (void)
3124 int sp_adjust;
3126 rtx Rb, Re;
3127 rtx sp_adjust_insn;
3129 /* Compute and setup stack frame size.
3130 The result will be in cfun->machine. */
3131 nds32_compute_stack_frame ();
3133 /* Prevent the instruction scheduler from
3134 moving instructions across the boundary. */
3135 emit_insn (gen_blockage ());
3137 /* If the function is 'naked', we do not have to generate
3138 epilogue code fragment BUT 'ret' instruction. */
3139 if (cfun->machine->naked_p)
3141 /* Generate return instruction by using
3142 unspec_volatile_func_return pattern.
3143 Make sure this instruction is after gen_blockage().
3144 NOTE that $lp will become 'live'
3145 after this instruction has been emitted. */
3146 emit_insn (gen_unspec_volatile_func_return ());
3147 return;
3150 /* Get callee_first_regno and callee_last_regno. */
3151 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3152 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3154 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3155 where imm8u has to be 8-byte alignment. */
3156 sp_adjust = cfun->machine->local_size
3157 + cfun->machine->out_args_size
3158 + cfun->machine->callee_saved_area_padding_bytes;
3160 /* We have to consider alloca issue as well.
3161 If the function does call alloca(), the stack pointer is not fixed.
3162 In that case, we cannot use 'pop25 Re,imm8u' directly.
3163 We have to caculate stack pointer from frame pointer
3164 and then use 'pop25 Re,0'.
3165 Of course, the frame_pointer_needed should be nonzero
3166 if the function calls alloca(). */
3167 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3168 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3169 && !cfun->calls_alloca)
3171 /* We can use 'pop25 Re,imm8u'. */
3173 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3174 the pattern 'stack_v3pop' is implementad in nds32.md.
3175 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3176 nds32_emit_stack_v3pop (Rb, Re,
3177 GEN_INT (14), GEN_INT (sp_adjust));
3179 else
3181 /* We have to use 'pop25 Re,0', and prior to it,
3182 we must expand one more instruction to adjust $sp. */
3184 if (frame_pointer_needed)
3186 /* adjust $sp = $fp - 4 ($fp size)
3187 - 4 ($gp size)
3188 - 4 ($lp size)
3189 - (4 * n) (callee-saved registers)
3190 Note: No need to adjust
3191 cfun->machine->callee_saved_area_padding_bytes,
3192 because we want to adjust stack pointer
3193 to the position for pop instruction. */
3194 sp_adjust = cfun->machine->fp_size
3195 + cfun->machine->gp_size
3196 + cfun->machine->lp_size
3197 + cfun->machine->callee_saved_regs_size;
3198 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3199 hard_frame_pointer_rtx,
3200 GEN_INT (-1 * sp_adjust));
3201 /* Emit rtx into instructions list and receive INSN rtx form. */
3202 sp_adjust_insn = emit_insn (sp_adjust_insn);
3204 else
3206 /* If frame pointer is NOT needed,
3207 we cannot calculate the sp adjustment from frame pointer.
3208 Instead, we calculate the adjustment by local_size,
3209 out_args_size, and callee_saved_area_padding_bytes.
3210 Notice that such sp adjustment value may be out of range,
3211 so we have to deal with it as well. */
3213 /* Adjust $sp = $sp + local_size + out_args_size
3214 + callee_saved_area_padding_bytes. */
3215 sp_adjust = cfun->machine->local_size
3216 + cfun->machine->out_args_size
3217 + cfun->machine->callee_saved_area_padding_bytes;
3218 /* sp_adjust value may be out of range of the addi instruction,
3219 create alternative add behavior with TA_REGNUM if necessary,
3220 using POSITIVE value to tell that we are increasing address. */
3221 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3222 if (sp_adjust)
3224 /* Generate sp adjustment instruction
3225 if and only if sp_adjust != 0. */
3226 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3227 stack_pointer_rtx,
3228 GEN_INT (sp_adjust));
3229 /* Emit rtx into instructions list and receive INSN rtx form. */
3230 sp_adjust_insn = emit_insn (sp_adjust_insn);
3234 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3235 the pattern 'stack_v3pop' is implementad in nds32.md. */
3236 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3237 nds32_emit_stack_v3pop (Rb, Re,
3238 GEN_INT (14), GEN_INT (0));
3242 /* ------------------------------------------------------------------------ */
3244 /* Function to test 333-form for load/store instructions.
3245 This is auxiliary extern function for auxiliary macro in nds32.h.
3246 Because it is a little complicated, we use function instead of macro. */
3247 bool
3248 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
3250 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3251 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3253 if (GET_MODE_SIZE (mode) == 4)
3254 return satisfies_constraint_Iu05 (imm);
3256 if (GET_MODE_SIZE (mode) == 2)
3257 return satisfies_constraint_Iu04 (imm);
3259 if (GET_MODE_SIZE (mode) == 1)
3260 return satisfies_constraint_Iu03 (imm);
3263 return false;
3267 /* Computing the Length of an Insn.
3268 Modifies the length assigned to instruction INSN.
3269 LEN is the initially computed length of the insn. */
3271 nds32_adjust_insn_length (rtx_insn *insn, int length)
3273 rtx src, dst;
3275 switch (recog_memoized (insn))
3277 case CODE_FOR_move_df:
3278 case CODE_FOR_move_di:
3279 /* Adjust length of movd44 to 2. */
3280 src = XEXP (PATTERN (insn), 1);
3281 dst = XEXP (PATTERN (insn), 0);
3283 if (REG_P (src)
3284 && REG_P (dst)
3285 && (REGNO (src) % 2) == 0
3286 && (REGNO (dst) % 2) == 0)
3287 length = 2;
3288 break;
3290 default:
3291 break;
3294 return length;
3298 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3300 nds32_target_alignment (rtx label)
3302 rtx insn;
3304 if (optimize_size)
3305 return 0;
3307 insn = next_active_insn (label);
3309 if (insn == 0)
3310 return 0;
3311 else if ((get_attr_length (insn) % 4) == 0)
3312 return 2;
3313 else
3314 return 0;
3317 /* ------------------------------------------------------------------------ */
3319 /* PART 5: Initialize target hook structure and definitions. */
3321 /* Controlling the Compilation Driver. */
3324 /* Run-time Target Specification. */
3327 /* Defining Data Structures for Per-function Information. */
3330 /* Storage Layout. */
3332 #undef TARGET_PROMOTE_FUNCTION_MODE
3333 #define TARGET_PROMOTE_FUNCTION_MODE \
3334 default_promote_function_mode_always_promote
3337 /* Layout of Source Language Data Types. */
3340 /* Register Usage. */
3342 /* -- Basic Characteristics of Registers. */
3344 /* -- Order of Allocation of Registers. */
3346 /* -- How Values Fit in Registers. */
3348 /* -- Handling Leaf Functions. */
3350 /* -- Registers That Form a Stack. */
3353 /* Register Classes. */
3355 #undef TARGET_CLASS_MAX_NREGS
3356 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3358 #undef TARGET_LRA_P
3359 #define TARGET_LRA_P hook_bool_void_true
3361 #undef TARGET_REGISTER_PRIORITY
3362 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3365 /* Obsolete Macros for Defining Constraints. */
3368 /* Stack Layout and Calling Conventions. */
3370 /* -- Basic Stack Layout. */
3372 /* -- Exception Handling Support. */
3374 /* -- Specifying How Stack Checking is Done. */
3376 /* -- Registers That Address the Stack Frame. */
3378 /* -- Eliminating Frame Pointer and Arg Pointer. */
3380 #undef TARGET_CAN_ELIMINATE
3381 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3383 /* -- Passing Function Arguments on the Stack. */
3385 /* -- Passing Arguments in Registers. */
3387 #undef TARGET_FUNCTION_ARG
3388 #define TARGET_FUNCTION_ARG nds32_function_arg
3390 #undef TARGET_FUNCTION_ARG_ADVANCE
3391 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3393 #undef TARGET_FUNCTION_ARG_BOUNDARY
3394 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3396 /* -- How Scalar Function Values Are Returned. */
3398 #undef TARGET_FUNCTION_VALUE
3399 #define TARGET_FUNCTION_VALUE nds32_function_value
3401 #undef TARGET_LIBCALL_VALUE
3402 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3404 #undef TARGET_FUNCTION_VALUE_REGNO_P
3405 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3407 /* -- How Large Values Are Returned. */
3409 /* -- Caller-Saves Register Allocation. */
3411 /* -- Function Entry and Exit. */
3413 #undef TARGET_ASM_FUNCTION_PROLOGUE
3414 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3416 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3417 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3419 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3420 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3422 #undef TARGET_ASM_FUNCTION_EPILOGUE
3423 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3425 #undef TARGET_ASM_OUTPUT_MI_THUNK
3426 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3428 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3429 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3431 /* -- Generating Code for Profiling. */
3433 /* -- Permitting tail calls. */
3435 #undef TARGET_WARN_FUNC_RETURN
3436 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3438 /* Stack smashing protection. */
3441 /* Implementing the Varargs Macros. */
3443 #undef TARGET_SETUP_INCOMING_VARARGS
3444 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3446 #undef TARGET_STRICT_ARGUMENT_NAMING
3447 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3450 /* Trampolines for Nested Functions. */
3452 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3453 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3455 #undef TARGET_TRAMPOLINE_INIT
3456 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3459 /* Implicit Calls to Library Routines. */
3462 /* Addressing Modes. */
3464 #undef TARGET_LEGITIMATE_ADDRESS_P
3465 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3468 /* Anchored Addresses. */
3471 /* Condition Code Status. */
3473 /* -- Representation of condition codes using (cc0). */
3475 /* -- Representation of condition codes using registers. */
3477 /* -- Macros to control conditional execution. */
3480 /* Describing Relative Costs of Operations. */
3482 #undef TARGET_REGISTER_MOVE_COST
3483 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3485 #undef TARGET_MEMORY_MOVE_COST
3486 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3488 #undef TARGET_RTX_COSTS
3489 #define TARGET_RTX_COSTS nds32_rtx_costs
3491 #undef TARGET_ADDRESS_COST
3492 #define TARGET_ADDRESS_COST nds32_address_cost
3495 /* Adjusting the Instruction Scheduler. */
3498 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3501 /* Position Independent Code. */
3504 /* Defining the Output Assembler Language. */
3506 /* -- The Overall Framework of an Assembler File. */
3508 #undef TARGET_ASM_FILE_START
3509 #define TARGET_ASM_FILE_START nds32_asm_file_start
3510 #undef TARGET_ASM_FILE_END
3511 #define TARGET_ASM_FILE_END nds32_asm_file_end
3513 /* -- Output of Data. */
3515 #undef TARGET_ASM_ALIGNED_HI_OP
3516 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3518 #undef TARGET_ASM_ALIGNED_SI_OP
3519 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3521 /* -- Output of Uninitialized Variables. */
3523 /* -- Output and Generation of Labels. */
3525 #undef TARGET_ASM_GLOBALIZE_LABEL
3526 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3528 /* -- How Initialization Functions Are Handled. */
3530 /* -- Macros Controlling Initialization Routines. */
3532 /* -- Output of Assembler Instructions. */
3534 #undef TARGET_PRINT_OPERAND
3535 #define TARGET_PRINT_OPERAND nds32_print_operand
3536 #undef TARGET_PRINT_OPERAND_ADDRESS
3537 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3539 /* -- Output of Dispatch Tables. */
3541 /* -- Assembler Commands for Exception Regions. */
3543 /* -- Assembler Commands for Alignment. */
3546 /* Controlling Debugging Information Format. */
3548 /* -- Macros Affecting All Debugging Formats. */
3550 /* -- Specific Options for DBX Output. */
3552 /* -- Open-Ended Hooks for DBX Format. */
3554 /* -- File Names in DBX Format. */
3556 /* -- Macros for SDB and DWARF Output. */
3558 /* -- Macros for VMS Debug Format. */
3561 /* Cross Compilation and Floating Point. */
3564 /* Mode Switching Instructions. */
3567 /* Defining target-specific uses of __attribute__. */
3569 #undef TARGET_ATTRIBUTE_TABLE
3570 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3572 #undef TARGET_MERGE_DECL_ATTRIBUTES
3573 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3575 #undef TARGET_INSERT_ATTRIBUTES
3576 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3578 #undef TARGET_OPTION_PRAGMA_PARSE
3579 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3581 #undef TARGET_OPTION_OVERRIDE
3582 #define TARGET_OPTION_OVERRIDE nds32_option_override
3585 /* Emulating TLS. */
3588 /* Defining coprocessor specifics for MIPS targets. */
3591 /* Parameters for Precompiled Header Validity Checking. */
3594 /* C++ ABI parameters. */
3597 /* Adding support for named address spaces. */
3600 /* Miscellaneous Parameters. */
3602 #undef TARGET_INIT_BUILTINS
3603 #define TARGET_INIT_BUILTINS nds32_init_builtins
3605 #undef TARGET_EXPAND_BUILTIN
3606 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3609 /* ------------------------------------------------------------------------ */
3611 /* Initialize the GCC target structure. */
3613 struct gcc_target targetm = TARGET_INITIALIZER;
3615 /* ------------------------------------------------------------------------ */