gcc/ada/
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob6fb2069cc54fe3d15936983512f5cc072311f29c
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 "hashtab.h"
42 #include "hash-set.h"
43 #include "vec.h"
44 #include "machmode.h"
45 #include "input.h"
46 #include "function.h"
47 #include "expr.h"
48 #include "recog.h"
49 #include "diagnostic-core.h"
50 #include "dominance.h"
51 #include "cfg.h"
52 #include "cfgrtl.h"
53 #include "cfganal.h"
54 #include "lcm.h"
55 #include "cfgbuild.h"
56 #include "cfgcleanup.h"
57 #include "predict.h"
58 #include "basic-block.h"
59 #include "df.h"
60 #include "tm_p.h"
61 #include "tm-constrs.h"
62 #include "optabs.h" /* For GEN_FCN. */
63 #include "target.h"
64 #include "target-def.h"
65 #include "langhooks.h" /* For add_builtin_function(). */
66 #include "ggc.h"
67 #include "builtins.h"
69 /* ------------------------------------------------------------------------ */
71 /* This file is divided into five parts:
73 PART 1: Auxiliary static variable definitions and
74 target hook static variable definitions.
76 PART 2: Auxiliary static function definitions.
78 PART 3: Implement target hook stuff definitions.
80 PART 4: Implemet extern function definitions,
81 the prototype is in nds32-protos.h.
83 PART 5: Initialize target hook structure and definitions. */
85 /* ------------------------------------------------------------------------ */
87 /* PART 1: Auxiliary static variable definitions and
88 target hook static variable definitions. */
90 /* Define intrinsic register names.
91 Please refer to nds32_intrinsic.h file, the index is corresponding to
92 'enum nds32_intrinsic_registers' data type values.
93 NOTE that the base value starting from 1024. */
94 static const char * const nds32_intrinsic_register_names[] =
96 "$PSW", "$IPSW", "$ITYPE", "$IPC"
99 /* Defining target-specific uses of __attribute__. */
100 static const struct attribute_spec nds32_attribute_table[] =
102 /* Syntax: { name, min_len, max_len, decl_required, type_required,
103 function_type_required, handler, affects_type_identity } */
105 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
106 { "interrupt", 1, 64, false, false, false, NULL, false },
107 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
108 { "exception", 1, 8, false, false, false, NULL, false },
109 /* Argument is user's interrupt numbers. The vector number is always 0. */
110 { "reset", 1, 1, false, false, false, NULL, false },
112 /* The attributes describing isr nested type. */
113 { "nested", 0, 0, false, false, false, NULL, false },
114 { "not_nested", 0, 0, false, false, false, NULL, false },
115 { "nested_ready", 0, 0, false, false, false, NULL, false },
117 /* The attributes describing isr register save scheme. */
118 { "save_all", 0, 0, false, false, false, NULL, false },
119 { "partial_save", 0, 0, false, false, false, NULL, false },
121 /* The attributes used by reset attribute. */
122 { "nmi", 1, 1, false, false, false, NULL, false },
123 { "warm", 1, 1, false, false, false, NULL, false },
125 /* The attribute telling no prologue/epilogue. */
126 { "naked", 0, 0, false, false, false, NULL, false },
128 /* The last attribute spec is set to be NULL. */
129 { NULL, 0, 0, false, false, false, NULL, false }
133 /* ------------------------------------------------------------------------ */
135 /* PART 2: Auxiliary static function definitions. */
137 /* Function to save and restore machine-specific function data. */
138 static struct machine_function *
139 nds32_init_machine_status (void)
141 struct machine_function *machine;
142 machine = ggc_cleared_alloc<machine_function> ();
144 /* Initially assume this function needs prologue/epilogue. */
145 machine->naked_p = 0;
147 /* Initially assume this function does NOT use fp_as_gp optimization. */
148 machine->fp_as_gp_p = 0;
150 return machine;
153 /* Function to compute stack frame size and
154 store into cfun->machine structure. */
155 static void
156 nds32_compute_stack_frame (void)
158 int r;
159 int block_size;
161 /* Because nds32_compute_stack_frame() will be called from different place,
162 everytime we enter this function, we have to assume this function
163 needs prologue/epilogue. */
164 cfun->machine->naked_p = 0;
166 /* Get variadic arguments size to prepare pretend arguments and
167 we will push them into stack at prologue by ourself. */
168 cfun->machine->va_args_size = crtl->args.pretend_args_size;
169 if (cfun->machine->va_args_size != 0)
171 cfun->machine->va_args_first_regno
172 = NDS32_GPR_ARG_FIRST_REGNUM
173 + NDS32_MAX_GPR_REGS_FOR_ARGS
174 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
175 cfun->machine->va_args_last_regno
176 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
178 else
180 cfun->machine->va_args_first_regno = SP_REGNUM;
181 cfun->machine->va_args_last_regno = SP_REGNUM;
184 /* Important: We need to make sure that varargs area is 8-byte alignment. */
185 block_size = cfun->machine->va_args_size;
186 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
188 cfun->machine->va_args_area_padding_bytes
189 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
192 /* Get local variables, incoming variables, and temporary variables size.
193 Note that we need to make sure it is 8-byte alignment because
194 there may be no padding bytes if we are using LRA. */
195 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
197 /* Get outgoing arguments size. */
198 cfun->machine->out_args_size = crtl->outgoing_args_size;
200 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
201 Check whether $fp is ever live. */
202 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
204 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
205 Check whether we are using PIC code genration. */
206 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
208 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
209 Check whether $lp is ever live. */
210 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
212 /* Initially there is no padding bytes. */
213 cfun->machine->callee_saved_area_padding_bytes = 0;
215 /* Calculate the bytes of saving callee-saved registers on stack. */
216 cfun->machine->callee_saved_regs_size = 0;
217 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
218 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
219 /* Currently, there is no need to check $r28~$r31
220 because we will save them in another way. */
221 for (r = 0; r < 28; r++)
223 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
225 /* Mark the first required callee-saved register
226 (only need to set it once).
227 If first regno == SP_REGNUM, we can tell that
228 it is the first time to be here. */
229 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
230 cfun->machine->callee_saved_regs_first_regno = r;
231 /* Mark the last required callee-saved register. */
232 cfun->machine->callee_saved_regs_last_regno = r;
236 /* Check if this function can omit prologue/epilogue code fragment.
237 If there is 'naked' attribute in this function,
238 we can set 'naked_p' flag to indicate that
239 we do not have to generate prologue/epilogue.
240 Or, if all the following conditions succeed,
241 we can set this function 'naked_p' as well:
242 condition 1: first_regno == last_regno == SP_REGNUM,
243 which means we do not have to save
244 any callee-saved registers.
245 condition 2: Both $lp and $fp are NOT live in this function,
246 which means we do not need to save them and there
247 is no outgoing size.
248 condition 3: There is no local_size, which means
249 we do not need to adjust $sp. */
250 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
251 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
252 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
253 && !df_regs_ever_live_p (FP_REGNUM)
254 && !df_regs_ever_live_p (LP_REGNUM)
255 && cfun->machine->local_size == 0))
257 /* Set this function 'naked_p' and other functions can check this flag.
258 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
259 callee-saved, local size, and outgoing size.
260 The varargs space and ret instruction may still present in
261 the prologue/epilogue expanding. */
262 cfun->machine->naked_p = 1;
264 /* No need to save $fp, $gp, and $lp.
265 We should set these value to be zero
266 so that nds32_initial_elimination_offset() can work properly. */
267 cfun->machine->fp_size = 0;
268 cfun->machine->gp_size = 0;
269 cfun->machine->lp_size = 0;
271 /* If stack usage computation is required,
272 we need to provide the static stack size. */
273 if (flag_stack_usage_info)
274 current_function_static_stack_size = 0;
276 /* No need to do following adjustment, return immediately. */
277 return;
280 /* Adjustment for v3push instructions:
281 If we are using v3push (push25/pop25) instructions,
282 we need to make sure Rb is $r6 and Re is
283 located on $r6, $r8, $r10, or $r14.
284 Some results above will be discarded and recomputed.
285 Note that it is only available under V3/V3M ISA and we
286 DO NOT setup following stuff for isr or variadic function. */
287 if (TARGET_V3PUSH
288 && !nds32_isr_function_p (current_function_decl)
289 && (cfun->machine->va_args_size == 0))
291 /* Recompute:
292 cfun->machine->fp_size
293 cfun->machine->gp_size
294 cfun->machine->lp_size
295 cfun->machine->callee_saved_regs_first_regno
296 cfun->machine->callee_saved_regs_last_regno */
298 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
299 cfun->machine->fp_size = 4;
300 cfun->machine->gp_size = 4;
301 cfun->machine->lp_size = 4;
303 /* Remember to set Rb = $r6. */
304 cfun->machine->callee_saved_regs_first_regno = 6;
306 if (cfun->machine->callee_saved_regs_last_regno <= 6)
308 /* Re = $r6 */
309 cfun->machine->callee_saved_regs_last_regno = 6;
311 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
313 /* Re = $r8 */
314 cfun->machine->callee_saved_regs_last_regno = 8;
316 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
318 /* Re = $r10 */
319 cfun->machine->callee_saved_regs_last_regno = 10;
321 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
323 /* Re = $r14 */
324 cfun->machine->callee_saved_regs_last_regno = 14;
326 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
328 /* If last_regno is SP_REGNUM, which means
329 it is never changed, so set it to Re = $r6. */
330 cfun->machine->callee_saved_regs_last_regno = 6;
332 else
334 /* The program flow should not go here. */
335 gcc_unreachable ();
339 /* We have correctly set callee_saved_regs_first_regno
340 and callee_saved_regs_last_regno.
341 Initially, the callee_saved_regs_size is supposed to be 0.
342 As long as callee_saved_regs_last_regno is not SP_REGNUM,
343 we can update callee_saved_regs_size with new size. */
344 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
346 /* Compute pushed size of callee-saved registers. */
347 cfun->machine->callee_saved_regs_size
348 = 4 * (cfun->machine->callee_saved_regs_last_regno
349 - cfun->machine->callee_saved_regs_first_regno
350 + 1);
353 /* Important: We need to make sure that
354 (fp_size + gp_size + lp_size + callee_saved_regs_size)
355 is 8-byte alignment.
356 If it is not, calculate the padding bytes. */
357 block_size = cfun->machine->fp_size
358 + cfun->machine->gp_size
359 + cfun->machine->lp_size
360 + cfun->machine->callee_saved_regs_size;
361 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
363 cfun->machine->callee_saved_area_padding_bytes
364 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
367 /* If stack usage computation is required,
368 we need to provide the static stack size. */
369 if (flag_stack_usage_info)
371 current_function_static_stack_size
372 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
373 + cfun->machine->local_size
374 + cfun->machine->out_args_size;
378 /* Function to create a parallel rtx pattern
379 which presents stack push multiple behavior.
380 The overall concept are:
381 "push registers to memory",
382 "adjust stack pointer". */
383 static void
384 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4)
386 int regno;
387 int extra_count;
388 int num_use_regs;
389 int par_index;
390 int offset;
391 int save_fp, save_gp, save_lp;
393 rtx reg;
394 rtx mem;
395 rtx push_rtx;
396 rtx adjust_sp_rtx;
397 rtx parallel_insn;
399 /* We need to provide a customized rtx which contains
400 necessary information for data analysis,
401 so we create a parallel rtx like this:
402 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
403 (reg:SI Rb))
404 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
405 (reg:SI Rb+1))
407 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
408 (reg:SI Re))
409 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
410 (reg:SI FP_REGNUM))
411 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
412 (reg:SI GP_REGNUM))
413 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
414 (reg:SI LP_REGNUM))
415 (set (reg:SI SP_REGNUM)
416 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
418 /* Determine whether we need to save $fp, $gp, or $lp. */
419 save_fp = INTVAL (En4) & 0x8;
420 save_gp = INTVAL (En4) & 0x4;
421 save_lp = INTVAL (En4) & 0x2;
423 /* Calculate the number of registers that will be pushed. */
424 extra_count = 0;
425 if (save_fp)
426 extra_count++;
427 if (save_gp)
428 extra_count++;
429 if (save_lp)
430 extra_count++;
431 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
432 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
433 num_use_regs = extra_count;
434 else
435 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
437 /* In addition to used registers,
438 we need one more space for (set sp sp-x) rtx. */
439 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
440 rtvec_alloc (num_use_regs + 1));
441 par_index = 0;
443 /* Initialize offset and start to create push behavior. */
444 offset = -(num_use_regs * 4);
446 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
447 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
449 /* Rb and Re may be SP_REGNUM.
450 We need to break this loop immediately. */
451 if (regno == SP_REGNUM)
452 break;
454 reg = gen_rtx_REG (SImode, regno);
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++;
465 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
466 if (save_fp)
468 reg = gen_rtx_REG (SImode, FP_REGNUM);
469 mem = gen_frame_mem (SImode, plus_constant (Pmode,
470 stack_pointer_rtx,
471 offset));
472 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
473 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
474 RTX_FRAME_RELATED_P (push_rtx) = 1;
475 offset = offset + 4;
476 par_index++;
478 if (save_gp)
480 reg = gen_rtx_REG (SImode, GP_REGNUM);
481 mem = gen_frame_mem (SImode, plus_constant (Pmode,
482 stack_pointer_rtx,
483 offset));
484 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
485 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
486 RTX_FRAME_RELATED_P (push_rtx) = 1;
487 offset = offset + 4;
488 par_index++;
490 if (save_lp)
492 reg = gen_rtx_REG (SImode, LP_REGNUM);
493 mem = gen_frame_mem (SImode, plus_constant (Pmode,
494 stack_pointer_rtx,
495 offset));
496 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
497 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
498 RTX_FRAME_RELATED_P (push_rtx) = 1;
499 offset = offset + 4;
500 par_index++;
503 /* Create (set sp sp-x). */
505 /* We need to re-calculate the offset value again for adjustment. */
506 offset = -(num_use_regs * 4);
507 adjust_sp_rtx
508 = gen_rtx_SET (VOIDmode,
509 stack_pointer_rtx,
510 plus_constant (Pmode, stack_pointer_rtx, offset));
511 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
512 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
514 parallel_insn = emit_insn (parallel_insn);
516 /* The insn rtx 'parallel_insn' will change frame layout.
517 We need to use RTX_FRAME_RELATED_P so that GCC is able to
518 generate CFI (Call Frame Information) stuff. */
519 RTX_FRAME_RELATED_P (parallel_insn) = 1;
522 /* Function to create a parallel rtx pattern
523 which presents stack pop multiple behavior.
524 The overall concept are:
525 "pop registers from memory",
526 "adjust stack pointer". */
527 static void
528 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
530 int regno;
531 int extra_count;
532 int num_use_regs;
533 int par_index;
534 int offset;
535 int save_fp, save_gp, save_lp;
537 rtx reg;
538 rtx mem;
539 rtx pop_rtx;
540 rtx adjust_sp_rtx;
541 rtx parallel_insn;
542 rtx dwarf = NULL_RTX;
544 /* We need to provide a customized rtx which contains
545 necessary information for data analysis,
546 so we create a parallel rtx like this:
547 (parallel [(set (reg:SI Rb)
548 (mem (reg:SI SP_REGNUM)))
549 (set (reg:SI Rb+1)
550 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
552 (set (reg:SI Re)
553 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
554 (set (reg:SI FP_REGNUM)
555 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
556 (set (reg:SI GP_REGNUM)
557 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
558 (set (reg:SI LP_REGNUM)
559 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
560 (set (reg:SI SP_REGNUM)
561 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
563 /* Determine whether we need to restore $fp, $gp, or $lp. */
564 save_fp = INTVAL (En4) & 0x8;
565 save_gp = INTVAL (En4) & 0x4;
566 save_lp = INTVAL (En4) & 0x2;
568 /* Calculate the number of registers that will be poped. */
569 extra_count = 0;
570 if (save_fp)
571 extra_count++;
572 if (save_gp)
573 extra_count++;
574 if (save_lp)
575 extra_count++;
576 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
577 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
578 num_use_regs = extra_count;
579 else
580 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
582 /* In addition to used registers,
583 we need one more space for (set sp sp+x) rtx. */
584 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
585 rtvec_alloc (num_use_regs + 1));
586 par_index = 0;
588 /* Initialize offset and start to create pop behavior. */
589 offset = 0;
591 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
592 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
594 /* Rb and Re may be SP_REGNUM.
595 We need to break this loop immediately. */
596 if (regno == SP_REGNUM)
597 break;
599 reg = gen_rtx_REG (SImode, regno);
600 mem = gen_frame_mem (SImode, plus_constant (Pmode,
601 stack_pointer_rtx,
602 offset));
603 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
604 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
605 RTX_FRAME_RELATED_P (pop_rtx) = 1;
606 offset = offset + 4;
607 par_index++;
609 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
612 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
613 if (save_fp)
615 reg = gen_rtx_REG (SImode, FP_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_gp)
629 reg = gen_rtx_REG (SImode, GP_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);
641 if (save_lp)
643 reg = gen_rtx_REG (SImode, LP_REGNUM);
644 mem = gen_frame_mem (SImode, plus_constant (Pmode,
645 stack_pointer_rtx,
646 offset));
647 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
648 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
649 RTX_FRAME_RELATED_P (pop_rtx) = 1;
650 offset = offset + 4;
651 par_index++;
653 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
656 /* Create (set sp sp+x). */
658 /* The offset value is already in place. No need to re-calculate it. */
659 adjust_sp_rtx
660 = gen_rtx_SET (VOIDmode,
661 stack_pointer_rtx,
662 plus_constant (Pmode, stack_pointer_rtx, offset));
663 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
665 /* Tell gcc we adjust SP in this insn. */
666 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
668 parallel_insn = emit_insn (parallel_insn);
670 /* The insn rtx 'parallel_insn' will change frame layout.
671 We need to use RTX_FRAME_RELATED_P so that GCC is able to
672 generate CFI (Call Frame Information) stuff. */
673 RTX_FRAME_RELATED_P (parallel_insn) = 1;
675 /* Add CFI info by manual. */
676 REG_NOTES (parallel_insn) = dwarf;
679 /* Function to create a parallel rtx pattern
680 which presents stack v3push behavior.
681 The overall concept are:
682 "push registers to memory",
683 "adjust stack pointer". */
684 static void
685 nds32_emit_stack_v3push (rtx Rb,
686 rtx Re,
687 rtx En4 ATTRIBUTE_UNUSED,
688 rtx imm8u)
690 int regno;
691 int num_use_regs;
692 int par_index;
693 int offset;
695 rtx reg;
696 rtx mem;
697 rtx push_rtx;
698 rtx adjust_sp_rtx;
699 rtx parallel_insn;
701 /* We need to provide a customized rtx which contains
702 necessary information for data analysis,
703 so we create a parallel rtx like this:
704 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
705 (reg:SI Rb))
706 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
707 (reg:SI Rb+1))
709 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
710 (reg:SI Re))
711 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
712 (reg:SI FP_REGNUM))
713 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
714 (reg:SI GP_REGNUM))
715 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
716 (reg:SI LP_REGNUM))
717 (set (reg:SI SP_REGNUM)
718 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
720 /* Calculate the number of registers that will be pushed.
721 Since $fp, $gp, and $lp is always pushed with v3push instruction,
722 we need to count these three registers.
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 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
727 /* In addition to used registers,
728 we need one more space for (set sp sp-x-imm8u) rtx. */
729 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
730 rtvec_alloc (num_use_regs + 1));
731 par_index = 0;
733 /* Initialize offset and start to create push behavior. */
734 offset = -(num_use_regs * 4);
736 /* Create (set mem regX) from Rb, Rb+1 up to Re.
737 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
738 So there is no need to worry about Rb=Re=SP_REGNUM case. */
739 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
741 reg = gen_rtx_REG (SImode, regno);
742 mem = gen_frame_mem (SImode, plus_constant (Pmode,
743 stack_pointer_rtx,
744 offset));
745 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
746 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
747 RTX_FRAME_RELATED_P (push_rtx) = 1;
748 offset = offset + 4;
749 par_index++;
752 /* Create (set mem fp). */
753 reg = gen_rtx_REG (SImode, FP_REGNUM);
754 mem = gen_frame_mem (SImode, plus_constant (Pmode,
755 stack_pointer_rtx,
756 offset));
757 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
758 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
759 RTX_FRAME_RELATED_P (push_rtx) = 1;
760 offset = offset + 4;
761 par_index++;
762 /* Create (set mem gp). */
763 reg = gen_rtx_REG (SImode, GP_REGNUM);
764 mem = gen_frame_mem (SImode, plus_constant (Pmode,
765 stack_pointer_rtx,
766 offset));
767 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
768 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
769 RTX_FRAME_RELATED_P (push_rtx) = 1;
770 offset = offset + 4;
771 par_index++;
772 /* Create (set mem lp). */
773 reg = gen_rtx_REG (SImode, LP_REGNUM);
774 mem = gen_frame_mem (SImode, plus_constant (Pmode,
775 stack_pointer_rtx,
776 offset));
777 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
778 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
779 RTX_FRAME_RELATED_P (push_rtx) = 1;
780 offset = offset + 4;
781 par_index++;
783 /* Create (set sp sp-x-imm8u). */
785 /* We need to re-calculate the offset value again for adjustment. */
786 offset = -(num_use_regs * 4);
787 adjust_sp_rtx
788 = gen_rtx_SET (VOIDmode,
789 stack_pointer_rtx,
790 plus_constant (Pmode,
791 stack_pointer_rtx,
792 offset - INTVAL (imm8u)));
793 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
794 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
796 parallel_insn = emit_insn (parallel_insn);
798 /* The insn rtx 'parallel_insn' will change frame layout.
799 We need to use RTX_FRAME_RELATED_P so that GCC is able to
800 generate CFI (Call Frame Information) stuff. */
801 RTX_FRAME_RELATED_P (parallel_insn) = 1;
804 /* Function to create a parallel rtx pattern
805 which presents stack v3pop behavior.
806 The overall concept are:
807 "pop registers from memory",
808 "adjust stack pointer". */
809 static void
810 nds32_emit_stack_v3pop (rtx Rb,
811 rtx Re,
812 rtx En4 ATTRIBUTE_UNUSED,
813 rtx imm8u)
815 int regno;
816 int num_use_regs;
817 int par_index;
818 int offset;
820 rtx reg;
821 rtx mem;
822 rtx pop_rtx;
823 rtx adjust_sp_rtx;
824 rtx parallel_insn;
825 rtx dwarf = NULL_RTX;
827 /* We need to provide a customized rtx which contains
828 necessary information for data analysis,
829 so we create a parallel rtx like this:
830 (parallel [(set (reg:SI Rb)
831 (mem (reg:SI SP_REGNUM)))
832 (set (reg:SI Rb+1)
833 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
835 (set (reg:SI Re)
836 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
837 (set (reg:SI FP_REGNUM)
838 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
839 (set (reg:SI GP_REGNUM)
840 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
841 (set (reg:SI LP_REGNUM)
842 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
843 (set (reg:SI SP_REGNUM)
844 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
846 /* Calculate the number of registers that will be poped.
847 Since $fp, $gp, and $lp is always poped with v3pop instruction,
848 we need to count these three registers.
849 Under v3push, 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 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
853 /* In addition to used registers,
854 we need one more space for (set sp sp+x+imm8u) rtx. */
855 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
856 rtvec_alloc (num_use_regs + 1));
857 par_index = 0;
859 /* Initialize offset and start to create pop behavior. */
860 offset = 0;
862 /* Create (set regX mem) from Rb, Rb+1 up to Re.
863 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
864 So there is no need to worry about Rb=Re=SP_REGNUM case. */
865 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
867 reg = gen_rtx_REG (SImode, regno);
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++;
877 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
880 /* Create (set fp mem). */
881 reg = gen_rtx_REG (SImode, FP_REGNUM);
882 mem = gen_frame_mem (SImode, plus_constant (Pmode,
883 stack_pointer_rtx,
884 offset));
885 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
886 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
887 RTX_FRAME_RELATED_P (pop_rtx) = 1;
888 offset = offset + 4;
889 par_index++;
890 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
892 /* Create (set gp mem). */
893 reg = gen_rtx_REG (SImode, GP_REGNUM);
894 mem = gen_frame_mem (SImode, plus_constant (Pmode,
895 stack_pointer_rtx,
896 offset));
897 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
898 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
899 RTX_FRAME_RELATED_P (pop_rtx) = 1;
900 offset = offset + 4;
901 par_index++;
902 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
904 /* Create (set lp mem ). */
905 reg = gen_rtx_REG (SImode, LP_REGNUM);
906 mem = gen_frame_mem (SImode, plus_constant (Pmode,
907 stack_pointer_rtx,
908 offset));
909 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
910 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
911 RTX_FRAME_RELATED_P (pop_rtx) = 1;
912 offset = offset + 4;
913 par_index++;
914 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
916 /* Create (set sp sp+x+imm8u). */
918 /* The offset value is already in place. No need to re-calculate it. */
919 adjust_sp_rtx
920 = gen_rtx_SET (VOIDmode,
921 stack_pointer_rtx,
922 plus_constant (Pmode,
923 stack_pointer_rtx,
924 offset + INTVAL (imm8u)));
925 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
927 /* Tell gcc we adjust SP in this insn. */
928 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
930 parallel_insn = emit_insn (parallel_insn);
932 /* The insn rtx 'parallel_insn' will change frame layout.
933 We need to use RTX_FRAME_RELATED_P so that GCC is able to
934 generate CFI (Call Frame Information) stuff. */
935 RTX_FRAME_RELATED_P (parallel_insn) = 1;
937 /* Add CFI info by manual. */
938 REG_NOTES (parallel_insn) = dwarf;
941 /* Function that may creates more instructions
942 for large value on adjusting stack pointer.
944 In nds32 target, 'addi' can be used for stack pointer
945 adjustment in prologue/epilogue stage.
946 However, sometimes there are too many local variables so that
947 the adjustment value is not able to be fit in the 'addi' instruction.
948 One solution is to move value into a register
949 and then use 'add' instruction.
950 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
951 Also, we need to return zero for sp adjustment so that
952 proglogue/epilogue knows there is no need to create 'addi' instruction. */
953 static int
954 nds32_force_addi_stack_int (int full_value)
956 int adjust_value;
958 rtx tmp_reg;
959 rtx sp_adjust_insn;
961 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
963 /* The value is not able to fit in single addi instruction.
964 Create more instructions of moving value into a register
965 and then add stack pointer with it. */
967 /* $r15 is going to be temporary register to hold the value. */
968 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
970 /* Create one more instruction to move value
971 into the temporary register. */
972 emit_move_insn (tmp_reg, GEN_INT (full_value));
974 /* Create new 'add' rtx. */
975 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
976 stack_pointer_rtx,
977 tmp_reg);
978 /* Emit rtx into insn list and receive its transformed insn rtx. */
979 sp_adjust_insn = emit_insn (sp_adjust_insn);
981 /* At prologue, we need to tell GCC that this is frame related insn,
982 so that we can consider this instruction to output debug information.
983 If full_value is NEGATIVE, it means this function
984 is invoked by expand_prologue. */
985 if (full_value < 0)
987 /* Because (tmp_reg <- full_value) may be split into two
988 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
989 We need to construct another (sp <- sp + full_value)
990 and then insert it into sp_adjust_insn's reg note to
991 represent a frame related expression.
992 GCC knows how to refer it and output debug information. */
994 rtx plus_rtx;
995 rtx set_rtx;
997 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
998 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
999 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
1001 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
1004 /* We have used alternative way to adjust stack pointer value.
1005 Return zero so that prologue/epilogue
1006 will not generate other instructions. */
1007 return 0;
1009 else
1011 /* The value is able to fit in addi instruction.
1012 However, remember to make it to be positive value
1013 because we want to return 'adjustment' result. */
1014 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1016 return adjust_value;
1020 /* Return true if MODE/TYPE need double word alignment. */
1021 static bool
1022 nds32_needs_double_word_align (machine_mode mode, const_tree type)
1024 unsigned int align;
1026 /* Pick up the alignment according to the mode or type. */
1027 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1029 return (align > PARM_BOUNDARY);
1032 /* Return true if FUNC is a naked function. */
1033 static bool
1034 nds32_naked_function_p (tree func)
1036 tree t;
1038 if (TREE_CODE (func) != FUNCTION_DECL)
1039 abort ();
1041 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1043 return (t != NULL_TREE);
1046 /* Function that check if 'X' is a valid address register.
1047 The variable 'STRICT' is very important to
1048 make decision for register number.
1050 STRICT : true
1051 => We are in reload pass or after reload pass.
1052 The register number should be strictly limited in general registers.
1054 STRICT : false
1055 => Before reload pass, we are free to use any register number. */
1056 static bool
1057 nds32_address_register_rtx_p (rtx x, bool strict)
1059 int regno;
1061 if (GET_CODE (x) != REG)
1062 return false;
1064 regno = REGNO (x);
1066 if (strict)
1067 return REGNO_OK_FOR_BASE_P (regno);
1068 else
1069 return true;
1072 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1074 OUTER_MODE : Machine mode of outer address rtx.
1075 INDEX : Check if this rtx is valid to be a index for address.
1076 STRICT : If it is true, we are in reload pass or after reload pass. */
1077 static bool
1078 nds32_legitimate_index_p (machine_mode outer_mode,
1079 rtx index,
1080 bool strict)
1082 int regno;
1083 rtx op0;
1084 rtx op1;
1086 switch (GET_CODE (index))
1088 case REG:
1089 regno = REGNO (index);
1090 /* If we are in reload pass or after reload pass,
1091 we need to limit it to general register. */
1092 if (strict)
1093 return REGNO_OK_FOR_INDEX_P (regno);
1094 else
1095 return true;
1097 case CONST_INT:
1098 /* The alignment of the integer value is determined by 'outer_mode'. */
1099 if (GET_MODE_SIZE (outer_mode) == 1)
1101 /* Further check if the value is legal for the 'outer_mode'. */
1102 if (!satisfies_constraint_Is15 (index))
1103 return false;
1105 /* Pass all test, the value is valid, return true. */
1106 return true;
1108 if (GET_MODE_SIZE (outer_mode) == 2
1109 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1111 /* Further check if the value is legal for the 'outer_mode'. */
1112 if (!satisfies_constraint_Is16 (index))
1113 return false;
1115 /* Pass all test, the value is valid, return true. */
1116 return true;
1118 if (GET_MODE_SIZE (outer_mode) == 4
1119 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1121 /* Further check if the value is legal for the 'outer_mode'. */
1122 if (!satisfies_constraint_Is17 (index))
1123 return false;
1125 /* Pass all test, the value is valid, return true. */
1126 return true;
1128 if (GET_MODE_SIZE (outer_mode) == 8
1129 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1131 /* Further check if the value is legal for the 'outer_mode'. */
1132 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1133 SImode)))
1134 return false;
1136 /* Pass all test, the value is valid, return true. */
1137 return true;
1140 return false;
1142 case MULT:
1143 op0 = XEXP (index, 0);
1144 op1 = XEXP (index, 1);
1146 if (REG_P (op0) && CONST_INT_P (op1))
1148 int multiplier;
1149 multiplier = INTVAL (op1);
1151 /* We only allow (mult reg const_int_1)
1152 or (mult reg const_int_2) or (mult reg const_int_4). */
1153 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1154 return false;
1156 regno = REGNO (op0);
1157 /* Limit it in general registers if we are
1158 in reload pass or after reload pass. */
1159 if(strict)
1160 return REGNO_OK_FOR_INDEX_P (regno);
1161 else
1162 return true;
1165 return false;
1167 case ASHIFT:
1168 op0 = XEXP (index, 0);
1169 op1 = XEXP (index, 1);
1171 if (REG_P (op0) && CONST_INT_P (op1))
1173 int sv;
1174 /* op1 is already the sv value for use to do left shift. */
1175 sv = INTVAL (op1);
1177 /* We only allow (ashift reg const_int_0)
1178 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1179 if (sv != 0 && sv != 1 && sv !=2)
1180 return false;
1182 regno = REGNO (op0);
1183 /* Limit it in general registers if we are
1184 in reload pass or after reload pass. */
1185 if(strict)
1186 return REGNO_OK_FOR_INDEX_P (regno);
1187 else
1188 return true;
1191 return false;
1193 default:
1194 return false;
1198 /* ------------------------------------------------------------------------ */
1200 /* PART 3: Implement target hook stuff definitions. */
1202 /* Register Classes. */
1204 static unsigned char
1205 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1206 machine_mode mode)
1208 /* Return the maximum number of consecutive registers
1209 needed to represent "mode" in a register of "rclass". */
1210 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1213 static int
1214 nds32_register_priority (int hard_regno)
1216 /* Encourage to use r0-r7 for LRA when optimize for size. */
1217 if (optimize_size && hard_regno < 8)
1218 return 4;
1219 return 3;
1223 /* Stack Layout and Calling Conventions. */
1225 /* There are three kinds of pointer concepts using in GCC compiler:
1227 frame pointer: A pointer to the first location of local variables.
1228 stack pointer: A pointer to the top of a stack frame.
1229 argument pointer: A pointer to the incoming arguments.
1231 In nds32 target calling convention, we are using 8-byte alignment.
1232 Besides, we would like to have each stack frame of a function includes:
1234 [Block A]
1235 1. previous hard frame pointer
1236 2. return address
1237 3. callee-saved registers
1238 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1239 and save it at
1240 cfun->machine->callee_saved_area_padding_bytes)
1242 [Block B]
1243 1. local variables
1244 2. spilling location
1245 3. <padding bytes> (it will be calculated by GCC itself)
1246 4. incoming arguments
1247 5. <padding bytes> (it will be calculated by GCC itself)
1249 [Block C]
1250 1. <padding bytes> (it will be calculated by GCC itself)
1251 2. outgoing arguments
1253 We 'wrap' these blocks together with
1254 hard frame pointer ($r28) and stack pointer ($r31).
1255 By applying the basic frame/stack/argument pointers concept,
1256 the layout of a stack frame shoule be like this:
1259 old stack pointer -> ----
1260 | | \
1261 | | saved arguments for
1262 | | vararg functions
1263 | | /
1264 hard frame pointer -> --
1265 & argument pointer | | \
1266 | | previous hardware frame pointer
1267 | | return address
1268 | | callee-saved registers
1269 | | /
1270 frame pointer -> --
1271 | | \
1272 | | local variables
1273 | | and incoming arguments
1274 | | /
1276 | | \
1277 | | outgoing
1278 | | arguments
1279 | | /
1280 stack pointer -> ----
1282 $SFP and $AP are used to represent frame pointer and arguments pointer,
1283 which will be both eliminated as hard frame pointer. */
1285 /* -- Eliminating Frame Pointer and Arg Pointer. */
1287 static bool
1288 nds32_can_eliminate (const int from_reg, const int to_reg)
1290 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1291 return true;
1293 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1294 return true;
1296 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1297 return true;
1299 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1300 return true;
1302 return false;
1305 /* -- Passing Arguments in Registers. */
1307 static rtx
1308 nds32_function_arg (cumulative_args_t ca, machine_mode mode,
1309 const_tree type, bool named)
1311 unsigned int regno;
1312 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1314 /* The last time this hook is called,
1315 it is called with MODE == VOIDmode. */
1316 if (mode == VOIDmode)
1317 return NULL_RTX;
1319 /* For nameless arguments, we need to take care it individually. */
1320 if (!named)
1322 /* If we are under hard float abi, we have arguments passed on the
1323 stack and all situation can be handled by GCC itself. */
1324 if (TARGET_HARD_FLOAT)
1325 return NULL_RTX;
1327 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1329 /* If we still have enough registers to pass argument, pick up
1330 next available register number. */
1331 regno
1332 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1333 return gen_rtx_REG (mode, regno);
1336 /* No register available, return NULL_RTX.
1337 The compiler will use stack to pass argument instead. */
1338 return NULL_RTX;
1341 /* The following is to handle named argument.
1342 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1343 are different. */
1344 if (TARGET_HARD_FLOAT)
1346 /* Currently we have not implemented hard float yet. */
1347 gcc_unreachable ();
1349 else
1351 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1352 argument. Since we allow to pass argument partially in registers,
1353 we can just return it if there are still registers available. */
1354 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1356 /* Pick up the next available register number. */
1357 regno
1358 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1359 return gen_rtx_REG (mode, regno);
1364 /* No register available, return NULL_RTX.
1365 The compiler will use stack to pass argument instead. */
1366 return NULL_RTX;
1369 static bool
1370 nds32_must_pass_in_stack (machine_mode mode, const_tree type)
1372 /* Return true if a type must be passed in memory.
1373 If it is NOT using hard float abi, small aggregates can be
1374 passed in a register even we are calling a variadic function.
1375 So there is no need to take padding into consideration. */
1376 if (TARGET_HARD_FLOAT)
1377 return must_pass_in_stack_var_size_or_pad (mode, type);
1378 else
1379 return must_pass_in_stack_var_size (mode, type);
1382 static int
1383 nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
1384 tree type, bool named ATTRIBUTE_UNUSED)
1386 /* Returns the number of bytes at the beginning of an argument that
1387 must be put in registers. The value must be zero for arguments that are
1388 passed entirely in registers or that are entirely pushed on the stack.
1389 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1390 first register to be used by the caller for this argument. */
1391 unsigned int needed_reg_count;
1392 unsigned int remaining_reg_count;
1393 CUMULATIVE_ARGS *cum;
1395 cum = get_cumulative_args (ca);
1397 /* Under hard float abi, we better have argument entirely passed in
1398 registers or pushed on the stack so that we can reduce the complexity
1399 of dealing with cum->gpr_offset and cum->fpr_offset. */
1400 if (TARGET_HARD_FLOAT)
1401 return 0;
1403 /* If we have already runned out of argument registers, return zero
1404 so that the argument will be entirely pushed on the stack. */
1405 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1406 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1407 return 0;
1409 /* Calculate how many registers do we need for this argument. */
1410 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1412 /* Calculate how many argument registers have left for passing argument.
1413 Note that we should count it from next available register number. */
1414 remaining_reg_count
1415 = NDS32_MAX_GPR_REGS_FOR_ARGS
1416 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1417 - NDS32_GPR_ARG_FIRST_REGNUM);
1419 /* Note that we have to return the nubmer of bytes, not registers count. */
1420 if (needed_reg_count > remaining_reg_count)
1421 return remaining_reg_count * UNITS_PER_WORD;
1423 return 0;
1426 static void
1427 nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
1428 const_tree type, bool named)
1430 machine_mode sub_mode;
1431 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1433 if (named)
1435 /* We need to further check TYPE and MODE so that we can determine
1436 which kind of register we shall advance. */
1437 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1438 sub_mode = TYPE_MODE (TREE_TYPE (type));
1439 else
1440 sub_mode = mode;
1442 /* Under hard float abi, we may advance FPR registers. */
1443 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1445 /* Currently we have not implemented hard float yet. */
1446 gcc_unreachable ();
1448 else
1450 cum->gpr_offset
1451 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1452 - NDS32_GPR_ARG_FIRST_REGNUM
1453 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1456 else
1458 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1459 we can advance next register as well so that caller is
1460 able to pass arguments in registers and callee must be
1461 in charge of pushing all of them into stack. */
1462 if (!TARGET_HARD_FLOAT)
1464 cum->gpr_offset
1465 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1466 - NDS32_GPR_ARG_FIRST_REGNUM
1467 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1472 static unsigned int
1473 nds32_function_arg_boundary (machine_mode mode, const_tree type)
1475 return (nds32_needs_double_word_align (mode, type)
1476 ? NDS32_DOUBLE_WORD_ALIGNMENT
1477 : PARM_BOUNDARY);
1480 /* -- How Scalar Function Values Are Returned. */
1482 static rtx
1483 nds32_function_value (const_tree ret_type,
1484 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1485 bool outgoing ATTRIBUTE_UNUSED)
1487 machine_mode mode;
1488 int unsignedp;
1490 mode = TYPE_MODE (ret_type);
1491 unsignedp = TYPE_UNSIGNED (ret_type);
1493 mode = promote_mode (ret_type, mode, &unsignedp);
1495 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1498 static rtx
1499 nds32_libcall_value (machine_mode mode,
1500 const_rtx fun ATTRIBUTE_UNUSED)
1502 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1505 static bool
1506 nds32_function_value_regno_p (const unsigned int regno)
1508 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1511 /* -- Function Entry and Exit. */
1513 /* The content produced from this function
1514 will be placed before prologue body. */
1515 static void
1516 nds32_asm_function_prologue (FILE *file,
1517 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1519 int r;
1520 const char *func_name;
1521 tree attrs;
1522 tree name;
1524 /* All stack frame information is supposed to be
1525 already computed when expanding prologue.
1526 The result is in cfun->machine.
1527 DO NOT call nds32_compute_stack_frame() here
1528 because it may corrupt the essential information. */
1530 fprintf (file, "\t! BEGIN PROLOGUE\n");
1531 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1532 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1533 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1534 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1536 /* Use df_regs_ever_live_p() to detect if the register
1537 is ever used in the current function. */
1538 fprintf (file, "\t! registers ever_live: ");
1539 for (r = 0; r < 32; r++)
1541 if (df_regs_ever_live_p (r))
1542 fprintf (file, "%s, ", reg_names[r]);
1544 fputc ('\n', file);
1546 /* Display the attributes of this function. */
1547 fprintf (file, "\t! function attributes: ");
1548 /* Get the attributes tree list.
1549 Note that GCC builds attributes list with reverse order. */
1550 attrs = DECL_ATTRIBUTES (current_function_decl);
1552 /* If there is no any attribute, print out "None". */
1553 if (!attrs)
1554 fprintf (file, "None");
1556 /* If there are some attributes, try if we need to
1557 construct isr vector information. */
1558 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1559 nds32_construct_isr_vectors_information (attrs, func_name);
1561 /* Display all attributes of this function. */
1562 while (attrs)
1564 name = TREE_PURPOSE (attrs);
1565 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1567 /* Pick up the next attribute. */
1568 attrs = TREE_CHAIN (attrs);
1570 fputc ('\n', file);
1573 /* After rtl prologue has been expanded, this function is used. */
1574 static void
1575 nds32_asm_function_end_prologue (FILE *file)
1577 fprintf (file, "\t! END PROLOGUE\n");
1579 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1580 we can generate special directive: ".omit_fp_begin"
1581 to guide linker doing fp-as-gp optimization.
1582 However, for a naked function, which means
1583 it should not have prologue/epilogue,
1584 using fp-as-gp still requires saving $fp by push/pop behavior and
1585 there is no benefit to use fp-as-gp on such small function.
1586 So we need to make sure this function is NOT naked as well. */
1587 if (!frame_pointer_needed
1588 && !cfun->machine->naked_p
1589 && cfun->machine->fp_as_gp_p)
1591 fprintf (file, "\t! ----------------------------------------\n");
1592 fprintf (file, "\t! Guide linker to do "
1593 "link time optimization: fp-as-gp\n");
1594 fprintf (file, "\t! We add one more instruction to "
1595 "initialize $fp near to $gp location.\n");
1596 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1597 fprintf (file, "\t! this extra instruction should be "
1598 "eliminated at link stage.\n");
1599 fprintf (file, "\t.omit_fp_begin\n");
1600 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1601 fprintf (file, "\t! ----------------------------------------\n");
1605 /* Before rtl epilogue has been expanded, this function is used. */
1606 static void
1607 nds32_asm_function_begin_epilogue (FILE *file)
1609 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1610 we can generate special directive: ".omit_fp_end"
1611 to claim fp-as-gp optimization range.
1612 However, for a naked function,
1613 which means it should not have prologue/epilogue,
1614 using fp-as-gp still requires saving $fp by push/pop behavior and
1615 there is no benefit to use fp-as-gp on such small function.
1616 So we need to make sure this function is NOT naked as well. */
1617 if (!frame_pointer_needed
1618 && !cfun->machine->naked_p
1619 && cfun->machine->fp_as_gp_p)
1621 fprintf (file, "\t! ----------------------------------------\n");
1622 fprintf (file, "\t! Claim the range of fp-as-gp "
1623 "link time optimization\n");
1624 fprintf (file, "\t.omit_fp_end\n");
1625 fprintf (file, "\t! ----------------------------------------\n");
1628 fprintf (file, "\t! BEGIN EPILOGUE\n");
1631 /* The content produced from this function
1632 will be placed after epilogue body. */
1633 static void
1634 nds32_asm_function_epilogue (FILE *file,
1635 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1637 fprintf (file, "\t! END EPILOGUE\n");
1640 static void
1641 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1642 HOST_WIDE_INT delta,
1643 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1644 tree function)
1646 int this_regno;
1648 /* Make sure unwind info is emitted for the thunk if needed. */
1649 final_start_function (emit_barrier (), file, 1);
1651 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1653 : 0);
1655 if (delta != 0)
1657 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1659 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1660 this_regno, this_regno, delta);
1662 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1664 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1665 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1667 else
1669 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1670 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1671 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1675 fprintf (file, "\tb\t");
1676 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1677 fprintf (file, "\n");
1679 final_end_function ();
1682 /* -- Permitting tail calls. */
1684 /* Determine whether we need to enable warning for function return check. */
1685 static bool
1686 nds32_warn_func_return (tree decl)
1688 /* Naked functions are implemented entirely in assembly, including the
1689 return sequence, so suppress warnings about this. */
1690 return !nds32_naked_function_p (decl);
1694 /* Implementing the Varargs Macros. */
1696 static void
1697 nds32_setup_incoming_varargs (cumulative_args_t ca,
1698 machine_mode mode,
1699 tree type,
1700 int *pretend_args_size,
1701 int second_time ATTRIBUTE_UNUSED)
1703 unsigned int total_args_regs;
1704 unsigned int num_of_used_regs;
1705 unsigned int remaining_reg_count;
1706 CUMULATIVE_ARGS *cum;
1708 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1709 So that all nameless arguments are pushed by caller and all situation
1710 can be handled by GCC itself. */
1711 if (TARGET_HARD_FLOAT)
1712 return;
1714 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1715 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1716 However, for nameless(anonymous) arguments, we should push them on the
1717 stack so that all the nameless arguments appear to have been passed
1718 consecutively in the memory for accessing. Hence, we need to check and
1719 exclude the registers that are used for named arguments. */
1721 cum = get_cumulative_args (ca);
1723 /* The MODE and TYPE describe the last argument.
1724 We need those information to determine the remaining registers
1725 for varargs. */
1726 total_args_regs
1727 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1728 num_of_used_regs
1729 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1730 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1732 remaining_reg_count = total_args_regs - num_of_used_regs;
1733 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1735 return;
1738 static bool
1739 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1741 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1742 true for named arguments, and false for unnamed arguments. */
1743 return true;
1747 /* Trampolines for Nested Functions. */
1749 static void
1750 nds32_asm_trampoline_template (FILE *f)
1752 if (TARGET_REDUCED_REGS)
1754 /* Trampoline is not supported on reduced-set registers yet. */
1755 sorry ("a nested function is not supported for reduced registers");
1757 else
1759 asm_fprintf (f, "\t! Trampoline code template\n");
1760 asm_fprintf (f, "\t! This code fragment will be copied "
1761 "into stack on demand\n");
1763 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1764 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1765 "! load nested function address\n");
1766 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1767 "! load chain_value\n");
1768 asm_fprintf (f, "\tjr\t$r15\n");
1771 /* Preserve space ($pc + 16) for saving chain_value,
1772 nds32_trampoline_init will fill the value in this slot. */
1773 asm_fprintf (f, "\t! space for saving chain_value\n");
1774 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1776 /* Preserve space ($pc + 20) for saving nested function address,
1777 nds32_trampoline_init will fill the value in this slot. */
1778 asm_fprintf (f, "\t! space for saving nested function address\n");
1779 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1782 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1783 static void
1784 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1786 int i;
1788 /* Nested function address. */
1789 rtx fnaddr;
1790 /* The memory rtx that is going to
1791 be filled with chain_value. */
1792 rtx chain_value_mem;
1793 /* The memory rtx that is going to
1794 be filled with nested function address. */
1795 rtx nested_func_mem;
1797 /* Start address of trampoline code in stack, for doing cache sync. */
1798 rtx sync_cache_addr;
1799 /* Temporary register for sync instruction. */
1800 rtx tmp_reg;
1801 /* Instruction-cache sync instruction,
1802 requesting an argument as starting address. */
1803 rtx isync_insn;
1804 /* For convenience reason of doing comparison. */
1805 int tramp_align_in_bytes;
1807 /* Trampoline is not supported on reduced-set registers yet. */
1808 if (TARGET_REDUCED_REGS)
1809 sorry ("a nested function is not supported for reduced registers");
1811 /* STEP 1: Copy trampoline code template into stack,
1812 fill up essential data into stack. */
1814 /* Extract nested function address rtx. */
1815 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1817 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1818 We have nds32_asm_trampoline_template() to emit template pattern. */
1819 emit_block_move (m_tramp, assemble_trampoline_template (),
1820 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1822 /* After copying trampoline code into stack,
1823 fill chain_value into stack. */
1824 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1825 emit_move_insn (chain_value_mem, chain_value);
1826 /* After copying trampoline code int stack,
1827 fill nested function address into stack. */
1828 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1829 emit_move_insn (nested_func_mem, fnaddr);
1831 /* STEP 2: Sync instruction-cache. */
1833 /* We have successfully filled trampoline code into stack.
1834 However, in order to execute code in stack correctly,
1835 we must sync instruction cache. */
1836 sync_cache_addr = XEXP (m_tramp, 0);
1837 tmp_reg = gen_reg_rtx (SImode);
1838 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1840 /* Because nds32_cache_block_size is in bytes,
1841 we get trampoline alignment in bytes for convenient comparison. */
1842 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1844 if (tramp_align_in_bytes >= nds32_cache_block_size
1845 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1847 /* Under this condition, the starting address of trampoline
1848 must be aligned to the starting address of each cache block
1849 and we do not have to worry about cross-boundary issue. */
1850 for (i = 0;
1851 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1852 / nds32_cache_block_size;
1853 i++)
1855 emit_move_insn (tmp_reg,
1856 plus_constant (Pmode, sync_cache_addr,
1857 nds32_cache_block_size * i));
1858 emit_insn (isync_insn);
1861 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1863 /* The starting address of trampoline code
1864 may not be aligned to the cache block,
1865 so the trampoline code may be across two cache block.
1866 We need to sync the last element, which is 4-byte size,
1867 of trampoline template. */
1868 for (i = 0;
1869 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1870 / nds32_cache_block_size;
1871 i++)
1873 emit_move_insn (tmp_reg,
1874 plus_constant (Pmode, sync_cache_addr,
1875 nds32_cache_block_size * i));
1876 emit_insn (isync_insn);
1879 /* The last element of trampoline template is 4-byte size. */
1880 emit_move_insn (tmp_reg,
1881 plus_constant (Pmode, sync_cache_addr,
1882 TRAMPOLINE_SIZE - 4));
1883 emit_insn (isync_insn);
1885 else
1887 /* This is the simplest case.
1888 Because TRAMPOLINE_SIZE is less than or
1889 equal to nds32_cache_block_size,
1890 we can just sync start address and
1891 the last element of trampoline code. */
1893 /* Sync starting address of tampoline code. */
1894 emit_move_insn (tmp_reg, sync_cache_addr);
1895 emit_insn (isync_insn);
1896 /* Sync the last element, which is 4-byte size,
1897 of trampoline template. */
1898 emit_move_insn (tmp_reg,
1899 plus_constant (Pmode, sync_cache_addr,
1900 TRAMPOLINE_SIZE - 4));
1901 emit_insn (isync_insn);
1904 /* Set instruction serialization barrier
1905 to guarantee the correct operations. */
1906 emit_insn (gen_unspec_volatile_isb ());
1910 /* Addressing Modes. */
1912 static bool
1913 nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1915 /* For (mem:DI addr) or (mem:DF addr) case,
1916 we only allow 'addr' to be [reg], [symbol_ref],
1917 [const], or [reg + const_int] pattern. */
1918 if (mode == DImode || mode == DFmode)
1920 /* Allow [Reg + const_int] addressing mode. */
1921 if (GET_CODE (x) == PLUS)
1923 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1924 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1925 && CONST_INT_P (XEXP (x, 1)))
1926 return true;
1928 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1929 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1930 && CONST_INT_P (XEXP (x, 0)))
1931 return true;
1934 /* Now check [reg], [symbol_ref], and [const]. */
1935 if (GET_CODE (x) != REG
1936 && GET_CODE (x) != SYMBOL_REF
1937 && GET_CODE (x) != CONST)
1938 return false;
1941 /* Check if 'x' is a valid address. */
1942 switch (GET_CODE (x))
1944 case REG:
1945 /* (mem (reg A)) => [Ra] */
1946 return nds32_address_register_rtx_p (x, strict);
1948 case SYMBOL_REF:
1950 if (!TARGET_GP_DIRECT
1951 && (reload_completed
1952 || reload_in_progress
1953 || lra_in_progress))
1954 return false;
1956 /* (mem (symbol_ref A)) => [symbol_ref] */
1957 return !currently_expanding_to_rtl;
1959 case CONST:
1961 if (!TARGET_GP_DIRECT
1962 && (reload_completed
1963 || reload_in_progress
1964 || lra_in_progress))
1965 return false;
1967 /* (mem (const (...)))
1968 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1969 if (GET_CODE (XEXP (x, 0)) == PLUS)
1971 rtx plus_op = XEXP (x, 0);
1973 rtx op0 = XEXP (plus_op, 0);
1974 rtx op1 = XEXP (plus_op, 1);
1976 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1977 return true;
1978 else
1979 return false;
1982 return false;
1984 case POST_MODIFY:
1985 /* (mem (post_modify (reg) (plus (reg) (reg))))
1986 => [Ra], Rb */
1987 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1988 => [Ra], const_int */
1989 if (GET_CODE (XEXP (x, 0)) == REG
1990 && GET_CODE (XEXP (x, 1)) == PLUS)
1992 rtx plus_op = XEXP (x, 1);
1994 rtx op0 = XEXP (plus_op, 0);
1995 rtx op1 = XEXP (plus_op, 1);
1997 if (nds32_address_register_rtx_p (op0, strict)
1998 && nds32_legitimate_index_p (mode, op1, strict))
1999 return true;
2000 else
2001 return false;
2004 return false;
2006 case POST_INC:
2007 case POST_DEC:
2008 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2009 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2010 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2011 We only need to deal with register Ra. */
2012 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2013 return true;
2014 else
2015 return false;
2017 case PLUS:
2018 /* (mem (plus reg const_int))
2019 => [Ra + imm] */
2020 /* (mem (plus reg reg))
2021 => [Ra + Rb] */
2022 /* (mem (plus (mult reg const_int) reg))
2023 => [Ra + Rb << sv] */
2024 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2025 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2026 return true;
2027 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2028 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2029 return true;
2030 else
2031 return false;
2033 case LO_SUM:
2034 if (!TARGET_GP_DIRECT)
2035 return true;
2037 default:
2038 return false;
2043 /* Describing Relative Costs of Operations. */
2045 static int
2046 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2047 reg_class_t from,
2048 reg_class_t to)
2050 if (from == HIGH_REGS || to == HIGH_REGS)
2051 return 6;
2053 return 2;
2056 static int
2057 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2058 reg_class_t rclass ATTRIBUTE_UNUSED,
2059 bool in ATTRIBUTE_UNUSED)
2061 return 8;
2064 /* This target hook describes the relative costs of RTL expressions.
2065 Return 'true' when all subexpressions of x have been processed.
2066 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2067 Refer to gcc/rtlanal.c for more information. */
2068 static bool
2069 nds32_rtx_costs (rtx x,
2070 int code,
2071 int outer_code,
2072 int opno,
2073 int *total,
2074 bool speed)
2076 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
2079 static int
2080 nds32_address_cost (rtx address,
2081 machine_mode mode,
2082 addr_space_t as,
2083 bool speed)
2085 return nds32_address_cost_impl (address, mode, as, speed);
2089 /* Defining the Output Assembler Language. */
2091 /* -- The Overall Framework of an Assembler File. */
2093 static void
2094 nds32_asm_file_start (void)
2096 default_file_start ();
2098 /* Tell assembler which ABI we are using. */
2099 fprintf (asm_out_file, "\t! ABI version\n");
2100 fprintf (asm_out_file, "\t.abi_2\n");
2102 /* Tell assembler that this asm code is generated by compiler. */
2103 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2104 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2105 /* Give assembler the size of each vector for interrupt handler. */
2106 fprintf (asm_out_file, "\t! This vector size directive is required "
2107 "for checking inconsistency on interrupt handler\n");
2108 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2110 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2111 the compiler may produce 'la $fp,_FP_BASE_' instruction
2112 at prologue for fp-as-gp optimization.
2113 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2114 in case user does not pass '--relax' option to linker. */
2115 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2117 fprintf (asm_out_file, "\t! This weak reference is required to do "
2118 "fp-as-gp link time optimization\n");
2119 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2121 /* If user enables '-mex9', we should emit relaxation directive
2122 to tell linker that this file is allowed to do ex9 optimization. */
2123 if (TARGET_EX9)
2125 fprintf (asm_out_file, "\t! This relaxation directive is required "
2126 "to do ex9 link time optimization\n");
2127 fprintf (asm_out_file, "\t.relax\tex9\n");
2130 fprintf (asm_out_file, "\t! ------------------------------------\n");
2132 if (TARGET_ISA_V2)
2133 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2134 if (TARGET_ISA_V3)
2135 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2136 if (TARGET_ISA_V3M)
2137 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2139 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2140 ((TARGET_BIG_ENDIAN) ? "big-endian"
2141 : "little-endian"));
2143 fprintf (asm_out_file, "\t! ------------------------------------\n");
2145 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2146 ((TARGET_CMOV) ? "Yes"
2147 : "No"));
2148 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2149 ((TARGET_PERF_EXT) ? "Yes"
2150 : "No"));
2152 fprintf (asm_out_file, "\t! ------------------------------------\n");
2154 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2155 ((TARGET_V3PUSH) ? "Yes"
2156 : "No"));
2157 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2158 ((TARGET_16_BIT) ? "Yes"
2159 : "No"));
2160 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
2161 ((TARGET_GP_DIRECT) ? "Yes"
2162 : "No"));
2163 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2164 ((TARGET_REDUCED_REGS) ? "Yes"
2165 : "No"));
2167 fprintf (asm_out_file, "\t! ------------------------------------\n");
2169 if (optimize_size)
2170 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2171 else
2172 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2174 fprintf (asm_out_file, "\t! ------------------------------------\n");
2176 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2177 nds32_cache_block_size);
2179 fprintf (asm_out_file, "\t! ------------------------------------\n");
2181 nds32_asm_file_start_for_isr ();
2184 static void
2185 nds32_asm_file_end (void)
2187 nds32_asm_file_end_for_isr ();
2189 fprintf (asm_out_file, "\t! ------------------------------------\n");
2192 /* -- Output and Generation of Labels. */
2194 static void
2195 nds32_asm_globalize_label (FILE *stream, const char *name)
2197 fputs ("\t.global\t", stream);
2198 assemble_name (stream, name);
2199 fputs ("\n", stream);
2202 /* -- Output of Assembler Instructions. */
2204 static void
2205 nds32_print_operand (FILE *stream, rtx x, int code)
2207 int op_value;
2209 switch (code)
2211 case 0 :
2212 /* Do nothing special. */
2213 break;
2215 case 'V':
2216 /* 'x' is supposed to be CONST_INT, get the value. */
2217 gcc_assert (CONST_INT_P (x));
2218 op_value = INTVAL (x);
2220 /* According to the Andes architecture,
2221 the system/user register index range is 0 ~ 1023.
2222 In order to avoid conflict between user-specified-integer value
2223 and enum-specified-register value,
2224 the 'enum nds32_intrinsic_registers' value
2225 in nds32_intrinsic.h starts from 1024. */
2226 if (op_value < 1024 && op_value >= 0)
2228 /* If user gives integer value directly (0~1023),
2229 we just print out the value. */
2230 fprintf (stream, "%d", op_value);
2232 else if (op_value < 0
2233 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2234 + 1024))
2236 /* The enum index value for array size is out of range. */
2237 error ("intrinsic register index is out of range");
2239 else
2241 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2242 we can print out register name. Remember to substract 1024. */
2243 fprintf (stream, "%s",
2244 nds32_intrinsic_register_names[op_value - 1024]);
2247 /* No need to handle following process, so return immediately. */
2248 return;
2250 default :
2251 /* Unknown flag. */
2252 output_operand_lossage ("invalid operand output code");
2253 break;
2256 switch (GET_CODE (x))
2258 case LABEL_REF:
2259 case SYMBOL_REF:
2260 output_addr_const (stream, x);
2261 break;
2263 case REG:
2264 /* Forbid using static chain register ($r16)
2265 on reduced-set registers configuration. */
2266 if (TARGET_REDUCED_REGS
2267 && REGNO (x) == STATIC_CHAIN_REGNUM)
2268 sorry ("a nested function is not supported for reduced registers");
2270 /* Normal cases, print out register name. */
2271 fputs (reg_names[REGNO (x)], stream);
2272 break;
2274 case MEM:
2275 output_address (XEXP (x, 0));
2276 break;
2278 case CODE_LABEL:
2279 case CONST_INT:
2280 case CONST:
2281 output_addr_const (stream, x);
2282 break;
2284 default:
2285 /* Generally, output_addr_const () is able to handle most cases.
2286 We want to see what CODE could appear,
2287 so we use gcc_unreachable() to stop it. */
2288 debug_rtx (x);
2289 gcc_unreachable ();
2290 break;
2294 static void
2295 nds32_print_operand_address (FILE *stream, rtx x)
2297 rtx op0, op1;
2299 switch (GET_CODE (x))
2301 case SYMBOL_REF:
2302 case CONST:
2303 /* [ + symbol_ref] */
2304 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2305 fputs ("[ + ", stream);
2306 output_addr_const (stream, x);
2307 fputs ("]", stream);
2308 break;
2310 case REG:
2311 /* Forbid using static chain register ($r16)
2312 on reduced-set registers configuration. */
2313 if (TARGET_REDUCED_REGS
2314 && REGNO (x) == STATIC_CHAIN_REGNUM)
2315 sorry ("a nested function is not supported for reduced registers");
2317 /* [Ra] */
2318 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2319 break;
2321 case PLUS:
2322 op0 = XEXP (x, 0);
2323 op1 = XEXP (x, 1);
2325 /* Checking op0, forbid using static chain register ($r16)
2326 on reduced-set registers configuration. */
2327 if (TARGET_REDUCED_REGS
2328 && REG_P (op0)
2329 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2330 sorry ("a nested function is not supported for reduced registers");
2331 /* Checking op1, forbid using static chain register ($r16)
2332 on reduced-set registers configuration. */
2333 if (TARGET_REDUCED_REGS
2334 && REG_P (op1)
2335 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2336 sorry ("a nested function is not supported for reduced registers");
2338 if (REG_P (op0) && CONST_INT_P (op1))
2340 /* [Ra + imm] */
2341 fprintf (stream, "[%s + (%d)]",
2342 reg_names[REGNO (op0)], (int)INTVAL (op1));
2344 else if (REG_P (op0) && REG_P (op1))
2346 /* [Ra + Rb] */
2347 fprintf (stream, "[%s + %s]",
2348 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2350 else if (GET_CODE (op0) == MULT && REG_P (op1))
2352 /* [Ra + Rb << sv]
2353 From observation, the pattern looks like:
2354 (plus:SI (mult:SI (reg:SI 58)
2355 (const_int 4 [0x4]))
2356 (reg/f:SI 57)) */
2357 int sv;
2359 /* We need to set sv to output shift value. */
2360 if (INTVAL (XEXP (op0, 1)) == 1)
2361 sv = 0;
2362 else if (INTVAL (XEXP (op0, 1)) == 2)
2363 sv = 1;
2364 else if (INTVAL (XEXP (op0, 1)) == 4)
2365 sv = 2;
2366 else
2367 gcc_unreachable ();
2369 fprintf (stream, "[%s + %s << %d]",
2370 reg_names[REGNO (op1)],
2371 reg_names[REGNO (XEXP (op0, 0))],
2372 sv);
2374 else
2376 /* The control flow is not supposed to be here. */
2377 debug_rtx (x);
2378 gcc_unreachable ();
2381 break;
2383 case POST_MODIFY:
2384 /* (post_modify (regA) (plus (regA) (regB)))
2385 (post_modify (regA) (plus (regA) (const_int)))
2386 We would like to extract
2387 regA and regB (or const_int) from plus rtx. */
2388 op0 = XEXP (XEXP (x, 1), 0);
2389 op1 = XEXP (XEXP (x, 1), 1);
2391 /* Checking op0, forbid using static chain register ($r16)
2392 on reduced-set registers configuration. */
2393 if (TARGET_REDUCED_REGS
2394 && REG_P (op0)
2395 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2396 sorry ("a nested function is not supported for reduced registers");
2397 /* Checking op1, forbid using static chain register ($r16)
2398 on reduced-set registers configuration. */
2399 if (TARGET_REDUCED_REGS
2400 && REG_P (op1)
2401 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2402 sorry ("a nested function is not supported for reduced registers");
2404 if (REG_P (op0) && REG_P (op1))
2406 /* [Ra], Rb */
2407 fprintf (stream, "[%s], %s",
2408 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2410 else if (REG_P (op0) && CONST_INT_P (op1))
2412 /* [Ra], imm */
2413 fprintf (stream, "[%s], %d",
2414 reg_names[REGNO (op0)], (int)INTVAL (op1));
2416 else
2418 /* The control flow is not supposed to be here. */
2419 debug_rtx (x);
2420 gcc_unreachable ();
2423 break;
2425 case POST_INC:
2426 case POST_DEC:
2427 op0 = XEXP (x, 0);
2429 /* Checking op0, forbid using static chain register ($r16)
2430 on reduced-set registers configuration. */
2431 if (TARGET_REDUCED_REGS
2432 && REG_P (op0)
2433 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2434 sorry ("a nested function is not supported for reduced registers");
2436 if (REG_P (op0))
2438 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2439 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2440 We only need to deal with register Ra. */
2441 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2443 else
2445 /* The control flow is not supposed to be here. */
2446 debug_rtx (x);
2447 gcc_unreachable ();
2450 break;
2452 default :
2453 /* Generally, output_addr_const () is able to handle most cases.
2454 We want to see what CODE could appear,
2455 so we use gcc_unreachable() to stop it. */
2456 debug_rtx (x);
2457 gcc_unreachable ();
2458 break;
2463 /* Defining target-specific uses of __attribute__. */
2465 /* Add some checking after merging attributes. */
2466 static tree
2467 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2469 tree combined_attrs;
2471 /* Create combined attributes. */
2472 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2473 DECL_ATTRIBUTES (newdecl));
2475 /* Since newdecl is acutally a duplicate of olddecl,
2476 we can take olddecl for some operations. */
2477 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2479 /* Check isr-specific attributes conflict. */
2480 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2483 return combined_attrs;
2486 /* Add some checking when inserting attributes. */
2487 static void
2488 nds32_insert_attributes (tree decl, tree *attributes)
2490 /* For function declaration, we need to check isr-specific attributes:
2491 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2492 2. Check valid integer value for interrupt/exception.
2493 3. Check valid integer value for reset.
2494 4. Check valid function for nmi/warm. */
2495 if (TREE_CODE (decl) == FUNCTION_DECL)
2497 tree func_attrs;
2498 tree intr, excp, reset;
2500 /* Pick up function attributes. */
2501 func_attrs = *attributes;
2503 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2504 nds32_check_isr_attrs_conflict (decl, func_attrs);
2506 /* Now we are starting to check valid id value
2507 for interrupt/exception/reset.
2508 Note that we ONLY check its validity here.
2509 To construct isr vector information, it is still performed
2510 by nds32_construct_isr_vectors_information(). */
2511 intr = lookup_attribute ("interrupt", func_attrs);
2512 excp = lookup_attribute ("exception", func_attrs);
2513 reset = lookup_attribute ("reset", func_attrs);
2515 if (intr || excp)
2517 /* Deal with interrupt/exception. */
2518 tree id_list;
2519 unsigned int lower_bound, upper_bound;
2521 /* The way to handle interrupt or exception is the same,
2522 we just need to take care of actual vector number.
2523 For interrupt(0..63), the actual vector number is (9..72).
2524 For exception(1..8), the actual vector number is (1..8). */
2525 lower_bound = (intr) ? (0) : (1);
2526 upper_bound = (intr) ? (63) : (8);
2528 /* Prepare id list so that we can traverse id value. */
2529 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2531 /* 2. Check valid integer value for interrupt/exception. */
2532 while (id_list)
2534 tree id;
2536 /* Pick up each vector id value. */
2537 id = TREE_VALUE (id_list);
2538 /* Issue error if it is not a valid integer value. */
2539 if (TREE_CODE (id) != INTEGER_CST
2540 || wi::ltu_p (id, lower_bound)
2541 || wi::gtu_p (id, upper_bound))
2542 error ("invalid id value for interrupt/exception attribute");
2544 /* Advance to next id. */
2545 id_list = TREE_CHAIN (id_list);
2548 else if (reset)
2550 /* Deal with reset. */
2551 tree id_list;
2552 tree id;
2553 tree nmi, warm;
2554 unsigned int lower_bound;
2555 unsigned int upper_bound;
2557 /* Prepare id_list and identify id value so that
2558 we can check if total number of vectors is valid. */
2559 id_list = TREE_VALUE (reset);
2560 id = TREE_VALUE (id_list);
2562 /* The maximum numbers for user's interrupt is 64. */
2563 lower_bound = 0;
2564 upper_bound = 64;
2566 /* 3. Check valid integer value for reset. */
2567 if (TREE_CODE (id) != INTEGER_CST
2568 || wi::ltu_p (id, lower_bound)
2569 || wi::gtu_p (id, upper_bound))
2570 error ("invalid id value for reset attribute");
2572 /* 4. Check valid function for nmi/warm. */
2573 nmi = lookup_attribute ("nmi", func_attrs);
2574 warm = lookup_attribute ("warm", func_attrs);
2576 if (nmi != NULL_TREE)
2578 tree nmi_func_list;
2579 tree nmi_func;
2581 nmi_func_list = TREE_VALUE (nmi);
2582 nmi_func = TREE_VALUE (nmi_func_list);
2584 /* Issue error if it is not a valid nmi function. */
2585 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2586 error ("invalid nmi function for reset attribute");
2589 if (warm != NULL_TREE)
2591 tree warm_func_list;
2592 tree warm_func;
2594 warm_func_list = TREE_VALUE (warm);
2595 warm_func = TREE_VALUE (warm_func_list);
2597 /* Issue error if it is not a valid warm function. */
2598 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2599 error ("invalid warm function for reset attribute");
2602 else
2604 /* No interrupt, exception, or reset attribute is set. */
2605 return;
2610 static bool
2611 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2612 tree pop_target ATTRIBUTE_UNUSED)
2614 /* Currently, we do not parse any pragma target by ourself,
2615 so just simply return false. */
2616 return false;
2619 static void
2620 nds32_option_override (void)
2622 /* After all the command options have been parsed,
2623 we shall deal with some flags for changing compiler settings. */
2625 /* At first, we check if we have to strictly
2626 set some flags based on ISA family. */
2627 if (TARGET_ISA_V2)
2629 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2630 target_flags &= ~MASK_V3PUSH;
2632 if (TARGET_ISA_V3)
2634 /* Under V3 ISA, currently nothing should be strictly set. */
2636 if (TARGET_ISA_V3M)
2638 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2639 target_flags |= MASK_REDUCED_REGS;
2640 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2641 target_flags &= ~MASK_PERF_EXT;
2644 /* See if we are using reduced-set registers:
2645 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2646 If so, we must forbid using $r11~$r14, $r16~$r27. */
2647 if (TARGET_REDUCED_REGS)
2649 int r;
2651 /* Prevent register allocator from
2652 choosing it as doing register allocation. */
2653 for (r = 11; r <= 14; r++)
2654 fixed_regs[r] = call_used_regs[r] = 1;
2655 for (r = 16; r <= 27; r++)
2656 fixed_regs[r] = call_used_regs[r] = 1;
2659 /* See if user explicitly would like to use fp-as-gp optimization.
2660 If so, we must prevent $fp from being allocated
2661 during register allocation. */
2662 if (TARGET_FORCE_FP_AS_GP)
2663 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2665 if (!TARGET_16_BIT)
2667 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2668 target_flags &= ~MASK_V3PUSH;
2671 /* Currently, we don't support PIC code generation yet. */
2672 if (flag_pic)
2673 sorry ("not support -fpic");
2677 /* Miscellaneous Parameters. */
2679 static void
2680 nds32_init_builtins (void)
2682 nds32_init_builtins_impl ();
2685 static rtx
2686 nds32_expand_builtin (tree exp,
2687 rtx target,
2688 rtx subtarget,
2689 machine_mode mode,
2690 int ignore)
2692 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2696 /* ------------------------------------------------------------------------ */
2698 /* PART 4: Implemet extern function definitions,
2699 the prototype is in nds32-protos.h. */
2701 /* Defining Data Structures for Per-function Information. */
2703 void
2704 nds32_init_expanders (void)
2706 /* Arrange to initialize and mark the machine per-function status. */
2707 init_machine_status = nds32_init_machine_status;
2711 /* Register Usage. */
2713 /* -- How Values Fit in Registers. */
2716 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2717 machine_mode mode)
2719 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2723 nds32_hard_regno_mode_ok (int regno, machine_mode mode)
2725 /* Restrict double-word quantities to even register pairs. */
2726 if (HARD_REGNO_NREGS (regno, mode) == 1
2727 || !((regno) & 1))
2728 return 1;
2730 return 0;
2734 /* Register Classes. */
2736 enum reg_class
2737 nds32_regno_reg_class (int regno)
2739 /* Refer to nds32.h for more register class details. */
2741 if (regno >= 0 && regno <= 7)
2742 return LOW_REGS;
2743 else if (regno >= 8 && regno <= 11)
2744 return MIDDLE_REGS;
2745 else if (regno >= 12 && regno <= 14)
2746 return HIGH_REGS;
2747 else if (regno == 15)
2748 return R15_TA_REG;
2749 else if (regno >= 16 && regno <= 19)
2750 return MIDDLE_REGS;
2751 else if (regno >= 20 && regno <= 31)
2752 return HIGH_REGS;
2753 else if (regno == 32 || regno == 33)
2754 return FRAME_REGS;
2755 else
2756 return NO_REGS;
2760 /* Stack Layout and Calling Conventions. */
2762 /* -- Basic Stack Layout. */
2765 nds32_return_addr_rtx (int count,
2766 rtx frameaddr ATTRIBUTE_UNUSED)
2768 /* There is no way to determine the return address
2769 if frameaddr is the frame that has 'count' steps
2770 up from current frame. */
2771 if (count != 0)
2772 return NULL_RTX;
2774 /* If count == 0, it means we are at current frame,
2775 the return address is $r30 ($lp). */
2776 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2779 /* -- Eliminating Frame Pointer and Arg Pointer. */
2781 HOST_WIDE_INT
2782 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2784 HOST_WIDE_INT offset;
2786 /* Compute and setup stack frame size.
2787 The result will be in cfun->machine. */
2788 nds32_compute_stack_frame ();
2790 /* Remember to consider
2791 cfun->machine->callee_saved_area_padding_bytes
2792 when calculating offset. */
2793 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2795 offset = (cfun->machine->fp_size
2796 + cfun->machine->gp_size
2797 + cfun->machine->lp_size
2798 + cfun->machine->callee_saved_regs_size
2799 + cfun->machine->callee_saved_area_padding_bytes
2800 + cfun->machine->local_size
2801 + cfun->machine->out_args_size);
2803 else if (from_reg == ARG_POINTER_REGNUM
2804 && to_reg == HARD_FRAME_POINTER_REGNUM)
2806 offset = 0;
2808 else if (from_reg == FRAME_POINTER_REGNUM
2809 && to_reg == STACK_POINTER_REGNUM)
2811 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2813 else if (from_reg == FRAME_POINTER_REGNUM
2814 && to_reg == HARD_FRAME_POINTER_REGNUM)
2816 offset = (-1) * (cfun->machine->fp_size
2817 + cfun->machine->gp_size
2818 + cfun->machine->lp_size
2819 + cfun->machine->callee_saved_regs_size
2820 + cfun->machine->callee_saved_area_padding_bytes);
2822 else
2824 gcc_unreachable ();
2827 return offset;
2830 /* -- Passing Arguments in Registers. */
2832 void
2833 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2834 tree fntype ATTRIBUTE_UNUSED,
2835 rtx libname ATTRIBUTE_UNUSED,
2836 tree fndecl ATTRIBUTE_UNUSED,
2837 int n_named_args ATTRIBUTE_UNUSED)
2839 /* Initial available registers
2840 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2841 for passing arguments. */
2842 cum->gpr_offset = 0;
2845 /* -- Function Entry and Exit. */
2847 /* Function for normal multiple push prologue. */
2848 void
2849 nds32_expand_prologue (void)
2851 int fp_adjust;
2852 int sp_adjust;
2853 int en4_const;
2855 rtx Rb, Re;
2856 rtx fp_adjust_insn, sp_adjust_insn;
2858 /* Compute and setup stack frame size.
2859 The result will be in cfun->machine. */
2860 nds32_compute_stack_frame ();
2862 /* If this is a variadic function, first we need to push argument
2863 registers that hold the unnamed argument value. */
2864 if (cfun->machine->va_args_size != 0)
2866 Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
2867 Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
2868 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2869 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0));
2871 /* We may also need to adjust stack pointer for padding bytes
2872 because varargs may cause $sp not 8-byte aligned. */
2873 if (cfun->machine->va_args_area_padding_bytes)
2875 /* Generate sp adjustment instruction. */
2876 sp_adjust = cfun->machine->va_args_area_padding_bytes;
2877 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2878 stack_pointer_rtx,
2879 GEN_INT (-1 * sp_adjust));
2881 /* Emit rtx into instructions list and receive INSN rtx form. */
2882 sp_adjust_insn = emit_insn (sp_adjust_insn);
2884 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2885 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2886 generate CFI (Call Frame Information) stuff. */
2887 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2891 /* If the function is 'naked',
2892 we do not have to generate prologue code fragment. */
2893 if (cfun->machine->naked_p)
2894 return;
2896 /* Get callee_first_regno and callee_last_regno. */
2897 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2898 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2900 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2901 the pattern 'stack_push_multiple' is implemented in nds32.md.
2902 For En4 field, we have to calculate its constant value.
2903 Refer to Andes ISA for more information. */
2904 en4_const = 0;
2905 if (cfun->machine->fp_size)
2906 en4_const += 8;
2907 if (cfun->machine->gp_size)
2908 en4_const += 4;
2909 if (cfun->machine->lp_size)
2910 en4_const += 2;
2912 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2913 to be saved, we don't have to create multiple push instruction.
2914 Otherwise, a multiple push instruction is needed. */
2915 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2917 /* Create multiple push instruction rtx. */
2918 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
2921 /* Check frame_pointer_needed to see
2922 if we shall emit fp adjustment instruction. */
2923 if (frame_pointer_needed)
2925 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2926 + (4 * callee-saved-registers)
2927 Note: No need to adjust
2928 cfun->machine->callee_saved_area_padding_bytes,
2929 because, at this point, stack pointer is just
2930 at the position after push instruction. */
2931 fp_adjust = cfun->machine->fp_size
2932 + cfun->machine->gp_size
2933 + cfun->machine->lp_size
2934 + cfun->machine->callee_saved_regs_size;
2935 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2936 stack_pointer_rtx,
2937 GEN_INT (fp_adjust));
2938 /* Emit rtx into instructions list and receive INSN rtx form. */
2939 fp_adjust_insn = emit_insn (fp_adjust_insn);
2942 /* Adjust $sp = $sp - local_size - out_args_size
2943 - callee_saved_area_padding_bytes. */
2944 sp_adjust = cfun->machine->local_size
2945 + cfun->machine->out_args_size
2946 + cfun->machine->callee_saved_area_padding_bytes;
2947 /* sp_adjust value may be out of range of the addi instruction,
2948 create alternative add behavior with TA_REGNUM if necessary,
2949 using NEGATIVE value to tell that we are decreasing address. */
2950 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2951 if (sp_adjust)
2953 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2954 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2955 stack_pointer_rtx,
2956 GEN_INT (-1 * sp_adjust));
2957 /* Emit rtx into instructions list and receive INSN rtx form. */
2958 sp_adjust_insn = emit_insn (sp_adjust_insn);
2960 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2961 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2962 generate CFI (Call Frame Information) stuff. */
2963 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2966 /* Prevent the instruction scheduler from
2967 moving instructions across the boundary. */
2968 emit_insn (gen_blockage ());
2971 /* Function for normal multiple pop epilogue. */
2972 void
2973 nds32_expand_epilogue (void)
2975 int sp_adjust;
2976 int en4_const;
2978 rtx Rb, Re;
2979 rtx sp_adjust_insn;
2981 /* Compute and setup stack frame size.
2982 The result will be in cfun->machine. */
2983 nds32_compute_stack_frame ();
2985 /* Prevent the instruction scheduler from
2986 moving instructions across the boundary. */
2987 emit_insn (gen_blockage ());
2989 /* If the function is 'naked', we do not have to generate
2990 epilogue code fragment BUT 'ret' instruction.
2991 However, if this function is also a variadic function,
2992 we need to create adjust stack pointer before 'ret' instruction. */
2993 if (cfun->machine->naked_p)
2995 /* If this is a variadic function, we do not have to restore argument
2996 registers but need to adjust stack pointer back to previous stack
2997 frame location before return. */
2998 if (cfun->machine->va_args_size != 0)
3000 /* Generate sp adjustment instruction.
3001 We need to consider padding bytes here. */
3002 sp_adjust = cfun->machine->va_args_size
3003 + cfun->machine->va_args_area_padding_bytes;
3004 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3005 stack_pointer_rtx,
3006 GEN_INT (sp_adjust));
3007 /* Emit rtx into instructions list and receive INSN rtx form. */
3008 sp_adjust_insn = emit_insn (sp_adjust_insn);
3010 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3011 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3012 generate CFI (Call Frame Information) stuff. */
3013 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3016 /* Generate return instruction by using
3017 unspec_volatile_func_return pattern.
3018 Make sure this instruction is after gen_blockage().
3019 NOTE that $lp will become 'live'
3020 after this instruction has been emitted. */
3021 emit_insn (gen_unspec_volatile_func_return ());
3022 return;
3025 if (frame_pointer_needed)
3027 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3028 - (4 * callee-saved-registers)
3029 Note: No need to adjust
3030 cfun->machine->callee_saved_area_padding_bytes,
3031 because we want to adjust stack pointer
3032 to the position for pop instruction. */
3033 sp_adjust = cfun->machine->fp_size
3034 + cfun->machine->gp_size
3035 + cfun->machine->lp_size
3036 + cfun->machine->callee_saved_regs_size;
3037 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3038 hard_frame_pointer_rtx,
3039 GEN_INT (-1 * sp_adjust));
3040 /* Emit rtx into instructions list and receive INSN rtx form. */
3041 sp_adjust_insn = emit_insn (sp_adjust_insn);
3043 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3044 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3046 else
3048 /* If frame pointer is NOT needed,
3049 we cannot calculate the sp adjustment from frame pointer.
3050 Instead, we calculate the adjustment by local_size,
3051 out_args_size, and callee_saved_area_padding_bytes.
3052 Notice that such sp adjustment value may be out of range,
3053 so we have to deal with it as well. */
3055 /* Adjust $sp = $sp + local_size + out_args_size
3056 + callee_saved_area_padding_bytes. */
3057 sp_adjust = cfun->machine->local_size
3058 + cfun->machine->out_args_size
3059 + cfun->machine->callee_saved_area_padding_bytes;
3060 /* sp_adjust value may be out of range of the addi instruction,
3061 create alternative add behavior with TA_REGNUM if necessary,
3062 using POSITIVE value to tell that we are increasing address. */
3063 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3064 if (sp_adjust)
3066 /* Generate sp adjustment instruction
3067 if and only if sp_adjust != 0. */
3068 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3069 stack_pointer_rtx,
3070 GEN_INT (sp_adjust));
3071 /* Emit rtx into instructions list and receive INSN rtx form. */
3072 sp_adjust_insn = emit_insn (sp_adjust_insn);
3074 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3075 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3079 /* Get callee_first_regno and callee_last_regno. */
3080 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3081 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3083 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3084 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3085 For En4 field, we have to calculate its constant value.
3086 Refer to Andes ISA for more information. */
3087 en4_const = 0;
3088 if (cfun->machine->fp_size)
3089 en4_const += 8;
3090 if (cfun->machine->gp_size)
3091 en4_const += 4;
3092 if (cfun->machine->lp_size)
3093 en4_const += 2;
3095 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3096 to be saved, we don't have to create multiple pop instruction.
3097 Otherwise, a multiple pop instruction is needed. */
3098 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3100 /* Create multiple pop instruction rtx. */
3101 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3104 /* If this is a variadic function, we do not have to restore argument
3105 registers but need to adjust stack pointer back to previous stack
3106 frame location before return. */
3107 if (cfun->machine->va_args_size != 0)
3109 /* Generate sp adjustment instruction.
3110 We need to consider padding bytes here. */
3111 sp_adjust = cfun->machine->va_args_size
3112 + cfun->machine->va_args_area_padding_bytes;
3113 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3114 stack_pointer_rtx,
3115 GEN_INT (sp_adjust));
3116 /* Emit rtx into instructions list and receive INSN rtx form. */
3117 sp_adjust_insn = emit_insn (sp_adjust_insn);
3119 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3120 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3121 generate CFI (Call Frame Information) stuff. */
3122 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3125 /* Generate return instruction by using
3126 unspec_volatile_func_return pattern. */
3127 emit_insn (gen_unspec_volatile_func_return ());
3130 /* Function for v3push prologue. */
3131 void
3132 nds32_expand_prologue_v3push (void)
3134 int fp_adjust;
3135 int sp_adjust;
3137 rtx Rb, Re;
3138 rtx fp_adjust_insn, sp_adjust_insn;
3140 /* Compute and setup stack frame size.
3141 The result will be in cfun->machine. */
3142 nds32_compute_stack_frame ();
3144 /* If the function is 'naked',
3145 we do not have to generate prologue code fragment. */
3146 if (cfun->machine->naked_p)
3147 return;
3149 /* Get callee_first_regno and callee_last_regno. */
3150 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3151 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3153 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3154 where imm8u has to be 8-byte alignment. */
3155 sp_adjust = cfun->machine->local_size
3156 + cfun->machine->out_args_size
3157 + cfun->machine->callee_saved_area_padding_bytes;
3159 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3160 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3162 /* We can use 'push25 Re,imm8u'. */
3164 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3165 the pattern 'stack_v3push' is implemented in nds32.md.
3166 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3167 nds32_emit_stack_v3push (Rb, Re,
3168 GEN_INT (14), GEN_INT (sp_adjust));
3170 /* Check frame_pointer_needed to see
3171 if we shall emit fp adjustment instruction. */
3172 if (frame_pointer_needed)
3174 /* adjust $fp = $sp + 4 ($fp size)
3175 + 4 ($gp size)
3176 + 4 ($lp size)
3177 + (4 * n) (callee-saved registers)
3178 + sp_adjust ('push25 Re,imm8u')
3179 Note: Since we use 'push25 Re,imm8u',
3180 the position of stack pointer is further
3181 changed after push instruction.
3182 Hence, we need to take sp_adjust value
3183 into consideration. */
3184 fp_adjust = cfun->machine->fp_size
3185 + cfun->machine->gp_size
3186 + cfun->machine->lp_size
3187 + cfun->machine->callee_saved_regs_size
3188 + sp_adjust;
3189 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3190 stack_pointer_rtx,
3191 GEN_INT (fp_adjust));
3192 /* Emit rtx into instructions list and receive INSN rtx form. */
3193 fp_adjust_insn = emit_insn (fp_adjust_insn);
3196 else
3198 /* We have to use 'push25 Re,0' and
3199 expand one more instruction to adjust $sp later. */
3201 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3202 the pattern 'stack_v3push' is implemented in nds32.md.
3203 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3204 nds32_emit_stack_v3push (Rb, Re,
3205 GEN_INT (14), GEN_INT (0));
3207 /* Check frame_pointer_needed to see
3208 if we shall emit fp adjustment instruction. */
3209 if (frame_pointer_needed)
3211 /* adjust $fp = $sp + 4 ($fp size)
3212 + 4 ($gp size)
3213 + 4 ($lp size)
3214 + (4 * n) (callee-saved registers)
3215 Note: Since we use 'push25 Re,0',
3216 the stack pointer is just at the position
3217 after push instruction.
3218 No need to take sp_adjust into consideration. */
3219 fp_adjust = cfun->machine->fp_size
3220 + cfun->machine->gp_size
3221 + cfun->machine->lp_size
3222 + cfun->machine->callee_saved_regs_size;
3223 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3224 stack_pointer_rtx,
3225 GEN_INT (fp_adjust));
3226 /* Emit rtx into instructions list and receive INSN rtx form. */
3227 fp_adjust_insn = emit_insn (fp_adjust_insn);
3230 /* Because we use 'push25 Re,0',
3231 we need to expand one more instruction to adjust $sp.
3232 However, sp_adjust value may be out of range of the addi instruction,
3233 create alternative add behavior with TA_REGNUM if necessary,
3234 using NEGATIVE value to tell that we are decreasing address. */
3235 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3236 if (sp_adjust)
3238 /* Generate sp adjustment instruction
3239 if and only if sp_adjust != 0. */
3240 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3241 stack_pointer_rtx,
3242 GEN_INT (-1 * sp_adjust));
3243 /* Emit rtx into instructions list and receive INSN rtx form. */
3244 sp_adjust_insn = emit_insn (sp_adjust_insn);
3246 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3247 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3248 generate CFI (Call Frame Information) stuff. */
3249 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3253 /* Prevent the instruction scheduler from
3254 moving instructions across the boundary. */
3255 emit_insn (gen_blockage ());
3258 /* Function for v3pop epilogue. */
3259 void
3260 nds32_expand_epilogue_v3pop (void)
3262 int sp_adjust;
3264 rtx Rb, Re;
3265 rtx sp_adjust_insn;
3267 /* Compute and setup stack frame size.
3268 The result will be in cfun->machine. */
3269 nds32_compute_stack_frame ();
3271 /* Prevent the instruction scheduler from
3272 moving instructions across the boundary. */
3273 emit_insn (gen_blockage ());
3275 /* If the function is 'naked', we do not have to generate
3276 epilogue code fragment BUT 'ret' instruction. */
3277 if (cfun->machine->naked_p)
3279 /* Generate return instruction by using
3280 unspec_volatile_func_return pattern.
3281 Make sure this instruction is after gen_blockage().
3282 NOTE that $lp will become 'live'
3283 after this instruction has been emitted. */
3284 emit_insn (gen_unspec_volatile_func_return ());
3285 return;
3288 /* Get callee_first_regno and callee_last_regno. */
3289 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3290 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3292 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3293 where imm8u has to be 8-byte alignment. */
3294 sp_adjust = cfun->machine->local_size
3295 + cfun->machine->out_args_size
3296 + cfun->machine->callee_saved_area_padding_bytes;
3298 /* We have to consider alloca issue as well.
3299 If the function does call alloca(), the stack pointer is not fixed.
3300 In that case, we cannot use 'pop25 Re,imm8u' directly.
3301 We have to caculate stack pointer from frame pointer
3302 and then use 'pop25 Re,0'.
3303 Of course, the frame_pointer_needed should be nonzero
3304 if the function calls alloca(). */
3305 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3306 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3307 && !cfun->calls_alloca)
3309 /* We can use 'pop25 Re,imm8u'. */
3311 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3312 the pattern 'stack_v3pop' is implementad in nds32.md.
3313 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3314 nds32_emit_stack_v3pop (Rb, Re,
3315 GEN_INT (14), GEN_INT (sp_adjust));
3317 else
3319 /* We have to use 'pop25 Re,0', and prior to it,
3320 we must expand one more instruction to adjust $sp. */
3322 if (frame_pointer_needed)
3324 /* adjust $sp = $fp - 4 ($fp size)
3325 - 4 ($gp size)
3326 - 4 ($lp size)
3327 - (4 * n) (callee-saved registers)
3328 Note: No need to adjust
3329 cfun->machine->callee_saved_area_padding_bytes,
3330 because we want to adjust stack pointer
3331 to the position for pop instruction. */
3332 sp_adjust = cfun->machine->fp_size
3333 + cfun->machine->gp_size
3334 + cfun->machine->lp_size
3335 + cfun->machine->callee_saved_regs_size;
3336 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3337 hard_frame_pointer_rtx,
3338 GEN_INT (-1 * sp_adjust));
3339 /* Emit rtx into instructions list and receive INSN rtx form. */
3340 sp_adjust_insn = emit_insn (sp_adjust_insn);
3342 else
3344 /* If frame pointer is NOT needed,
3345 we cannot calculate the sp adjustment from frame pointer.
3346 Instead, we calculate the adjustment by local_size,
3347 out_args_size, and callee_saved_area_padding_bytes.
3348 Notice that such sp adjustment value may be out of range,
3349 so we have to deal with it as well. */
3351 /* Adjust $sp = $sp + local_size + out_args_size
3352 + callee_saved_area_padding_bytes. */
3353 sp_adjust = cfun->machine->local_size
3354 + cfun->machine->out_args_size
3355 + cfun->machine->callee_saved_area_padding_bytes;
3356 /* sp_adjust value may be out of range of the addi instruction,
3357 create alternative add behavior with TA_REGNUM if necessary,
3358 using POSITIVE value to tell that we are increasing address. */
3359 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3360 if (sp_adjust)
3362 /* Generate sp adjustment instruction
3363 if and only if sp_adjust != 0. */
3364 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3365 stack_pointer_rtx,
3366 GEN_INT (sp_adjust));
3367 /* Emit rtx into instructions list and receive INSN rtx form. */
3368 sp_adjust_insn = emit_insn (sp_adjust_insn);
3372 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3373 the pattern 'stack_v3pop' is implementad in nds32.md. */
3374 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3375 nds32_emit_stack_v3pop (Rb, Re,
3376 GEN_INT (14), GEN_INT (0));
3380 /* ------------------------------------------------------------------------ */
3382 /* Function to test 333-form for load/store instructions.
3383 This is auxiliary extern function for auxiliary macro in nds32.h.
3384 Because it is a little complicated, we use function instead of macro. */
3385 bool
3386 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
3388 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3389 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3391 if (GET_MODE_SIZE (mode) == 4)
3392 return satisfies_constraint_Iu05 (imm);
3394 if (GET_MODE_SIZE (mode) == 2)
3395 return satisfies_constraint_Iu04 (imm);
3397 if (GET_MODE_SIZE (mode) == 1)
3398 return satisfies_constraint_Iu03 (imm);
3401 return false;
3405 /* Computing the Length of an Insn.
3406 Modifies the length assigned to instruction INSN.
3407 LEN is the initially computed length of the insn. */
3409 nds32_adjust_insn_length (rtx_insn *insn, int length)
3411 rtx src, dst;
3413 switch (recog_memoized (insn))
3415 case CODE_FOR_move_df:
3416 case CODE_FOR_move_di:
3417 /* Adjust length of movd44 to 2. */
3418 src = XEXP (PATTERN (insn), 1);
3419 dst = XEXP (PATTERN (insn), 0);
3421 if (REG_P (src)
3422 && REG_P (dst)
3423 && (REGNO (src) % 2) == 0
3424 && (REGNO (dst) % 2) == 0)
3425 length = 2;
3426 break;
3428 default:
3429 break;
3432 return length;
3436 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3438 nds32_target_alignment (rtx label)
3440 rtx_insn *insn;
3442 if (optimize_size)
3443 return 0;
3445 insn = next_active_insn (label);
3447 if (insn == 0)
3448 return 0;
3449 else if ((get_attr_length (insn) % 4) == 0)
3450 return 2;
3451 else
3452 return 0;
3455 /* ------------------------------------------------------------------------ */
3457 /* PART 5: Initialize target hook structure and definitions. */
3459 /* Controlling the Compilation Driver. */
3462 /* Run-time Target Specification. */
3465 /* Defining Data Structures for Per-function Information. */
3468 /* Storage Layout. */
3470 #undef TARGET_PROMOTE_FUNCTION_MODE
3471 #define TARGET_PROMOTE_FUNCTION_MODE \
3472 default_promote_function_mode_always_promote
3475 /* Layout of Source Language Data Types. */
3478 /* Register Usage. */
3480 /* -- Basic Characteristics of Registers. */
3482 /* -- Order of Allocation of Registers. */
3484 /* -- How Values Fit in Registers. */
3486 /* -- Handling Leaf Functions. */
3488 /* -- Registers That Form a Stack. */
3491 /* Register Classes. */
3493 #undef TARGET_CLASS_MAX_NREGS
3494 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3496 #undef TARGET_LRA_P
3497 #define TARGET_LRA_P hook_bool_void_true
3499 #undef TARGET_REGISTER_PRIORITY
3500 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3503 /* Obsolete Macros for Defining Constraints. */
3506 /* Stack Layout and Calling Conventions. */
3508 /* -- Basic Stack Layout. */
3510 /* -- Exception Handling Support. */
3512 /* -- Specifying How Stack Checking is Done. */
3514 /* -- Registers That Address the Stack Frame. */
3516 /* -- Eliminating Frame Pointer and Arg Pointer. */
3518 #undef TARGET_CAN_ELIMINATE
3519 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3521 /* -- Passing Function Arguments on the Stack. */
3523 /* -- Passing Arguments in Registers. */
3525 #undef TARGET_FUNCTION_ARG
3526 #define TARGET_FUNCTION_ARG nds32_function_arg
3528 #undef TARGET_MUST_PASS_IN_STACK
3529 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3531 #undef TARGET_ARG_PARTIAL_BYTES
3532 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3534 #undef TARGET_FUNCTION_ARG_ADVANCE
3535 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3537 #undef TARGET_FUNCTION_ARG_BOUNDARY
3538 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3540 /* -- How Scalar Function Values Are Returned. */
3542 #undef TARGET_FUNCTION_VALUE
3543 #define TARGET_FUNCTION_VALUE nds32_function_value
3545 #undef TARGET_LIBCALL_VALUE
3546 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3548 #undef TARGET_FUNCTION_VALUE_REGNO_P
3549 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3551 /* -- How Large Values Are Returned. */
3553 /* -- Caller-Saves Register Allocation. */
3555 /* -- Function Entry and Exit. */
3557 #undef TARGET_ASM_FUNCTION_PROLOGUE
3558 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3560 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3561 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3563 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3564 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3566 #undef TARGET_ASM_FUNCTION_EPILOGUE
3567 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3569 #undef TARGET_ASM_OUTPUT_MI_THUNK
3570 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3572 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3573 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3575 /* -- Generating Code for Profiling. */
3577 /* -- Permitting tail calls. */
3579 #undef TARGET_WARN_FUNC_RETURN
3580 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3582 /* Stack smashing protection. */
3585 /* Implementing the Varargs Macros. */
3587 #undef TARGET_SETUP_INCOMING_VARARGS
3588 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3590 #undef TARGET_STRICT_ARGUMENT_NAMING
3591 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3594 /* Trampolines for Nested Functions. */
3596 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3597 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3599 #undef TARGET_TRAMPOLINE_INIT
3600 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3603 /* Implicit Calls to Library Routines. */
3606 /* Addressing Modes. */
3608 #undef TARGET_LEGITIMATE_ADDRESS_P
3609 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3612 /* Anchored Addresses. */
3615 /* Condition Code Status. */
3617 /* -- Representation of condition codes using (cc0). */
3619 /* -- Representation of condition codes using registers. */
3621 /* -- Macros to control conditional execution. */
3624 /* Describing Relative Costs of Operations. */
3626 #undef TARGET_REGISTER_MOVE_COST
3627 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3629 #undef TARGET_MEMORY_MOVE_COST
3630 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3632 #undef TARGET_RTX_COSTS
3633 #define TARGET_RTX_COSTS nds32_rtx_costs
3635 #undef TARGET_ADDRESS_COST
3636 #define TARGET_ADDRESS_COST nds32_address_cost
3639 /* Adjusting the Instruction Scheduler. */
3642 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3645 /* Position Independent Code. */
3648 /* Defining the Output Assembler Language. */
3650 /* -- The Overall Framework of an Assembler File. */
3652 #undef TARGET_ASM_FILE_START
3653 #define TARGET_ASM_FILE_START nds32_asm_file_start
3654 #undef TARGET_ASM_FILE_END
3655 #define TARGET_ASM_FILE_END nds32_asm_file_end
3657 /* -- Output of Data. */
3659 #undef TARGET_ASM_ALIGNED_HI_OP
3660 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3662 #undef TARGET_ASM_ALIGNED_SI_OP
3663 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3665 /* -- Output of Uninitialized Variables. */
3667 /* -- Output and Generation of Labels. */
3669 #undef TARGET_ASM_GLOBALIZE_LABEL
3670 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3672 /* -- How Initialization Functions Are Handled. */
3674 /* -- Macros Controlling Initialization Routines. */
3676 /* -- Output of Assembler Instructions. */
3678 #undef TARGET_PRINT_OPERAND
3679 #define TARGET_PRINT_OPERAND nds32_print_operand
3680 #undef TARGET_PRINT_OPERAND_ADDRESS
3681 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3683 /* -- Output of Dispatch Tables. */
3685 /* -- Assembler Commands for Exception Regions. */
3687 /* -- Assembler Commands for Alignment. */
3690 /* Controlling Debugging Information Format. */
3692 /* -- Macros Affecting All Debugging Formats. */
3694 /* -- Specific Options for DBX Output. */
3696 /* -- Open-Ended Hooks for DBX Format. */
3698 /* -- File Names in DBX Format. */
3700 /* -- Macros for SDB and DWARF Output. */
3702 /* -- Macros for VMS Debug Format. */
3705 /* Cross Compilation and Floating Point. */
3708 /* Mode Switching Instructions. */
3711 /* Defining target-specific uses of __attribute__. */
3713 #undef TARGET_ATTRIBUTE_TABLE
3714 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3716 #undef TARGET_MERGE_DECL_ATTRIBUTES
3717 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3719 #undef TARGET_INSERT_ATTRIBUTES
3720 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3722 #undef TARGET_OPTION_PRAGMA_PARSE
3723 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3725 #undef TARGET_OPTION_OVERRIDE
3726 #define TARGET_OPTION_OVERRIDE nds32_option_override
3729 /* Emulating TLS. */
3732 /* Defining coprocessor specifics for MIPS targets. */
3735 /* Parameters for Precompiled Header Validity Checking. */
3738 /* C++ ABI parameters. */
3741 /* Adding support for named address spaces. */
3744 /* Miscellaneous Parameters. */
3746 #undef TARGET_INIT_BUILTINS
3747 #define TARGET_INIT_BUILTINS nds32_init_builtins
3749 #undef TARGET_EXPAND_BUILTIN
3750 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3753 /* ------------------------------------------------------------------------ */
3755 /* Initialize the GCC target structure. */
3757 struct gcc_target targetm = TARGET_INITIALIZER;
3759 /* ------------------------------------------------------------------------ */