[NDS32] Provide TARGET_CMODEL_[SMALL|MEDIUM|LARGE] to check which code model is speci...
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob91e797efbbf97bf5cd5663f18715f0fcb6afe212
1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2015 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 "hash-set.h"
28 #include "machmode.h"
29 #include "vec.h"
30 #include "double-int.h"
31 #include "input.h"
32 #include "alias.h"
33 #include "symtab.h"
34 #include "wide-int.h"
35 #include "inchash.h"
36 #include "tree.h"
37 #include "stor-layout.h"
38 #include "varasm.h"
39 #include "calls.h"
40 #include "rtl.h"
41 #include "regs.h"
42 #include "hard-reg-set.h"
43 #include "insn-config.h" /* Required by recog.h. */
44 #include "conditions.h"
45 #include "output.h"
46 #include "insn-attr.h" /* For DFA state_t. */
47 #include "insn-codes.h" /* For CODE_FOR_xxx. */
48 #include "reload.h" /* For push_reload(). */
49 #include "flags.h"
50 #include "input.h"
51 #include "function.h"
52 #include "expr.h"
53 #include "recog.h"
54 #include "diagnostic-core.h"
55 #include "dominance.h"
56 #include "cfg.h"
57 #include "cfgrtl.h"
58 #include "cfganal.h"
59 #include "lcm.h"
60 #include "cfgbuild.h"
61 #include "cfgcleanup.h"
62 #include "predict.h"
63 #include "basic-block.h"
64 #include "df.h"
65 #include "tm_p.h"
66 #include "tm-constrs.h"
67 #include "optabs.h" /* For GEN_FCN. */
68 #include "target.h"
69 #include "target-def.h"
70 #include "langhooks.h" /* For add_builtin_function(). */
71 #include "ggc.h"
72 #include "builtins.h"
74 /* ------------------------------------------------------------------------ */
76 /* This file is divided into five parts:
78 PART 1: Auxiliary static variable definitions and
79 target hook static variable definitions.
81 PART 2: Auxiliary static function definitions.
83 PART 3: Implement target hook stuff definitions.
85 PART 4: Implemet extern function definitions,
86 the prototype is in nds32-protos.h.
88 PART 5: Initialize target hook structure and definitions. */
90 /* ------------------------------------------------------------------------ */
92 /* PART 1: Auxiliary static variable definitions and
93 target hook static variable definitions. */
95 /* Define intrinsic register names.
96 Please refer to nds32_intrinsic.h file, the index is corresponding to
97 'enum nds32_intrinsic_registers' data type values.
98 NOTE that the base value starting from 1024. */
99 static const char * const nds32_intrinsic_register_names[] =
101 "$PSW", "$IPSW", "$ITYPE", "$IPC"
104 /* Defining target-specific uses of __attribute__. */
105 static const struct attribute_spec nds32_attribute_table[] =
107 /* Syntax: { name, min_len, max_len, decl_required, type_required,
108 function_type_required, handler, affects_type_identity } */
110 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
111 { "interrupt", 1, 64, false, false, false, NULL, false },
112 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
113 { "exception", 1, 8, false, false, false, NULL, false },
114 /* Argument is user's interrupt numbers. The vector number is always 0. */
115 { "reset", 1, 1, false, false, false, NULL, false },
117 /* The attributes describing isr nested type. */
118 { "nested", 0, 0, false, false, false, NULL, false },
119 { "not_nested", 0, 0, false, false, false, NULL, false },
120 { "nested_ready", 0, 0, false, false, false, NULL, false },
122 /* The attributes describing isr register save scheme. */
123 { "save_all", 0, 0, false, false, false, NULL, false },
124 { "partial_save", 0, 0, false, false, false, NULL, false },
126 /* The attributes used by reset attribute. */
127 { "nmi", 1, 1, false, false, false, NULL, false },
128 { "warm", 1, 1, false, false, false, NULL, false },
130 /* The attribute telling no prologue/epilogue. */
131 { "naked", 0, 0, false, false, false, NULL, false },
133 /* The last attribute spec is set to be NULL. */
134 { NULL, 0, 0, false, false, false, NULL, false }
138 /* ------------------------------------------------------------------------ */
140 /* PART 2: Auxiliary static function definitions. */
142 /* Function to save and restore machine-specific function data. */
143 static struct machine_function *
144 nds32_init_machine_status (void)
146 struct machine_function *machine;
147 machine = ggc_cleared_alloc<machine_function> ();
149 /* Initially assume this function needs prologue/epilogue. */
150 machine->naked_p = 0;
152 /* Initially assume this function does NOT use fp_as_gp optimization. */
153 machine->fp_as_gp_p = 0;
155 return machine;
158 /* Function to compute stack frame size and
159 store into cfun->machine structure. */
160 static void
161 nds32_compute_stack_frame (void)
163 int r;
164 int block_size;
166 /* Because nds32_compute_stack_frame() will be called from different place,
167 everytime we enter this function, we have to assume this function
168 needs prologue/epilogue. */
169 cfun->machine->naked_p = 0;
171 /* Get variadic arguments size to prepare pretend arguments and
172 we will push them into stack at prologue by ourself. */
173 cfun->machine->va_args_size = crtl->args.pretend_args_size;
174 if (cfun->machine->va_args_size != 0)
176 cfun->machine->va_args_first_regno
177 = NDS32_GPR_ARG_FIRST_REGNUM
178 + NDS32_MAX_GPR_REGS_FOR_ARGS
179 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
180 cfun->machine->va_args_last_regno
181 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
183 else
185 cfun->machine->va_args_first_regno = SP_REGNUM;
186 cfun->machine->va_args_last_regno = SP_REGNUM;
189 /* Important: We need to make sure that varargs area is 8-byte alignment. */
190 block_size = cfun->machine->va_args_size;
191 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
193 cfun->machine->va_args_area_padding_bytes
194 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
197 /* Get local variables, incoming variables, and temporary variables size.
198 Note that we need to make sure it is 8-byte alignment because
199 there may be no padding bytes if we are using LRA. */
200 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
202 /* Get outgoing arguments size. */
203 cfun->machine->out_args_size = crtl->outgoing_args_size;
205 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
206 Check whether $fp is ever live. */
207 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
209 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
210 Check whether we are using PIC code genration. */
211 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
213 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
214 Check whether $lp is ever live. */
215 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
217 /* Initially there is no padding bytes. */
218 cfun->machine->callee_saved_area_padding_bytes = 0;
220 /* Calculate the bytes of saving callee-saved registers on stack. */
221 cfun->machine->callee_saved_regs_size = 0;
222 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
223 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
224 /* Currently, there is no need to check $r28~$r31
225 because we will save them in another way. */
226 for (r = 0; r < 28; r++)
228 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
230 /* Mark the first required callee-saved register
231 (only need to set it once).
232 If first regno == SP_REGNUM, we can tell that
233 it is the first time to be here. */
234 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
235 cfun->machine->callee_saved_regs_first_regno = r;
236 /* Mark the last required callee-saved register. */
237 cfun->machine->callee_saved_regs_last_regno = r;
241 /* Check if this function can omit prologue/epilogue code fragment.
242 If there is 'naked' attribute in this function,
243 we can set 'naked_p' flag to indicate that
244 we do not have to generate prologue/epilogue.
245 Or, if all the following conditions succeed,
246 we can set this function 'naked_p' as well:
247 condition 1: first_regno == last_regno == SP_REGNUM,
248 which means we do not have to save
249 any callee-saved registers.
250 condition 2: Both $lp and $fp are NOT live in this function,
251 which means we do not need to save them and there
252 is no outgoing size.
253 condition 3: There is no local_size, which means
254 we do not need to adjust $sp. */
255 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
256 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
257 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
258 && !df_regs_ever_live_p (FP_REGNUM)
259 && !df_regs_ever_live_p (LP_REGNUM)
260 && cfun->machine->local_size == 0))
262 /* Set this function 'naked_p' and other functions can check this flag.
263 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
264 callee-saved, local size, and outgoing size.
265 The varargs space and ret instruction may still present in
266 the prologue/epilogue expanding. */
267 cfun->machine->naked_p = 1;
269 /* No need to save $fp, $gp, and $lp.
270 We should set these value to be zero
271 so that nds32_initial_elimination_offset() can work properly. */
272 cfun->machine->fp_size = 0;
273 cfun->machine->gp_size = 0;
274 cfun->machine->lp_size = 0;
276 /* If stack usage computation is required,
277 we need to provide the static stack size. */
278 if (flag_stack_usage_info)
279 current_function_static_stack_size = 0;
281 /* No need to do following adjustment, return immediately. */
282 return;
285 /* Adjustment for v3push instructions:
286 If we are using v3push (push25/pop25) instructions,
287 we need to make sure Rb is $r6 and Re is
288 located on $r6, $r8, $r10, or $r14.
289 Some results above will be discarded and recomputed.
290 Note that it is only available under V3/V3M ISA and we
291 DO NOT setup following stuff for isr or variadic function. */
292 if (TARGET_V3PUSH
293 && !nds32_isr_function_p (current_function_decl)
294 && (cfun->machine->va_args_size == 0))
296 /* Recompute:
297 cfun->machine->fp_size
298 cfun->machine->gp_size
299 cfun->machine->lp_size
300 cfun->machine->callee_saved_regs_first_regno
301 cfun->machine->callee_saved_regs_last_regno */
303 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
304 cfun->machine->fp_size = 4;
305 cfun->machine->gp_size = 4;
306 cfun->machine->lp_size = 4;
308 /* Remember to set Rb = $r6. */
309 cfun->machine->callee_saved_regs_first_regno = 6;
311 if (cfun->machine->callee_saved_regs_last_regno <= 6)
313 /* Re = $r6 */
314 cfun->machine->callee_saved_regs_last_regno = 6;
316 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
318 /* Re = $r8 */
319 cfun->machine->callee_saved_regs_last_regno = 8;
321 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
323 /* Re = $r10 */
324 cfun->machine->callee_saved_regs_last_regno = 10;
326 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
328 /* Re = $r14 */
329 cfun->machine->callee_saved_regs_last_regno = 14;
331 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
333 /* If last_regno is SP_REGNUM, which means
334 it is never changed, so set it to Re = $r6. */
335 cfun->machine->callee_saved_regs_last_regno = 6;
337 else
339 /* The program flow should not go here. */
340 gcc_unreachable ();
344 /* We have correctly set callee_saved_regs_first_regno
345 and callee_saved_regs_last_regno.
346 Initially, the callee_saved_regs_size is supposed to be 0.
347 As long as callee_saved_regs_last_regno is not SP_REGNUM,
348 we can update callee_saved_regs_size with new size. */
349 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
351 /* Compute pushed size of callee-saved registers. */
352 cfun->machine->callee_saved_regs_size
353 = 4 * (cfun->machine->callee_saved_regs_last_regno
354 - cfun->machine->callee_saved_regs_first_regno
355 + 1);
358 /* Important: We need to make sure that
359 (fp_size + gp_size + lp_size + callee_saved_regs_size)
360 is 8-byte alignment.
361 If it is not, calculate the padding bytes. */
362 block_size = cfun->machine->fp_size
363 + cfun->machine->gp_size
364 + cfun->machine->lp_size
365 + cfun->machine->callee_saved_regs_size;
366 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
368 cfun->machine->callee_saved_area_padding_bytes
369 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
372 /* If stack usage computation is required,
373 we need to provide the static stack size. */
374 if (flag_stack_usage_info)
376 current_function_static_stack_size
377 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
378 + cfun->machine->local_size
379 + cfun->machine->out_args_size;
383 /* Function to create a parallel rtx pattern
384 which presents stack push multiple behavior.
385 The overall concept are:
386 "push registers to memory",
387 "adjust stack pointer". */
388 static void
389 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p)
391 int regno;
392 int extra_count;
393 int num_use_regs;
394 int par_index;
395 int offset;
396 int save_fp, save_gp, save_lp;
398 rtx reg;
399 rtx mem;
400 rtx push_rtx;
401 rtx adjust_sp_rtx;
402 rtx parallel_insn;
403 rtx dwarf;
405 /* We need to provide a customized rtx which contains
406 necessary information for data analysis,
407 so we create a parallel rtx like this:
408 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
409 (reg:SI Rb))
410 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
411 (reg:SI Rb+1))
413 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
414 (reg:SI Re))
415 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
416 (reg:SI FP_REGNUM))
417 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
418 (reg:SI GP_REGNUM))
419 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
420 (reg:SI LP_REGNUM))
421 (set (reg:SI SP_REGNUM)
422 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
424 /* Determine whether we need to save $fp, $gp, or $lp. */
425 save_fp = INTVAL (En4) & 0x8;
426 save_gp = INTVAL (En4) & 0x4;
427 save_lp = INTVAL (En4) & 0x2;
429 /* Calculate the number of registers that will be pushed. */
430 extra_count = 0;
431 if (save_fp)
432 extra_count++;
433 if (save_gp)
434 extra_count++;
435 if (save_lp)
436 extra_count++;
437 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
438 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
439 num_use_regs = extra_count;
440 else
441 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
443 /* In addition to used registers,
444 we need one more space for (set sp sp-x) rtx. */
445 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
446 rtvec_alloc (num_use_regs + 1));
447 par_index = 0;
449 /* Initialize offset and start to create push behavior. */
450 offset = -(num_use_regs * 4);
452 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
453 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
455 /* Rb and Re may be SP_REGNUM.
456 We need to break this loop immediately. */
457 if (regno == SP_REGNUM)
458 break;
460 reg = gen_rtx_REG (SImode, regno);
461 mem = gen_frame_mem (SImode, plus_constant (Pmode,
462 stack_pointer_rtx,
463 offset));
464 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
465 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
466 RTX_FRAME_RELATED_P (push_rtx) = 1;
467 offset = offset + 4;
468 par_index++;
471 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
472 if (save_fp)
474 reg = gen_rtx_REG (SImode, FP_REGNUM);
475 mem = gen_frame_mem (SImode, plus_constant (Pmode,
476 stack_pointer_rtx,
477 offset));
478 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
479 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
480 RTX_FRAME_RELATED_P (push_rtx) = 1;
481 offset = offset + 4;
482 par_index++;
484 if (save_gp)
486 reg = gen_rtx_REG (SImode, GP_REGNUM);
487 mem = gen_frame_mem (SImode, plus_constant (Pmode,
488 stack_pointer_rtx,
489 offset));
490 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
491 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
492 RTX_FRAME_RELATED_P (push_rtx) = 1;
493 offset = offset + 4;
494 par_index++;
496 if (save_lp)
498 reg = gen_rtx_REG (SImode, LP_REGNUM);
499 mem = gen_frame_mem (SImode, plus_constant (Pmode,
500 stack_pointer_rtx,
501 offset));
502 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
503 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
504 RTX_FRAME_RELATED_P (push_rtx) = 1;
505 offset = offset + 4;
506 par_index++;
509 /* Create (set sp sp-x). */
511 /* We need to re-calculate the offset value again for adjustment. */
512 offset = -(num_use_regs * 4);
513 adjust_sp_rtx
514 = gen_rtx_SET (VOIDmode,
515 stack_pointer_rtx,
516 plus_constant (Pmode, stack_pointer_rtx, offset));
517 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
518 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
520 parallel_insn = emit_insn (parallel_insn);
522 /* The insn rtx 'parallel_insn' will change frame layout.
523 We need to use RTX_FRAME_RELATED_P so that GCC is able to
524 generate CFI (Call Frame Information) stuff. */
525 RTX_FRAME_RELATED_P (parallel_insn) = 1;
527 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
528 since we will not restore those register at epilogue. */
529 if (vaarg_p)
531 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
532 copy_rtx (adjust_sp_rtx), NULL_RTX);
533 REG_NOTES (parallel_insn) = dwarf;
537 /* Function to create a parallel rtx pattern
538 which presents stack pop multiple behavior.
539 The overall concept are:
540 "pop registers from memory",
541 "adjust stack pointer". */
542 static void
543 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
545 int regno;
546 int extra_count;
547 int num_use_regs;
548 int par_index;
549 int offset;
550 int save_fp, save_gp, save_lp;
552 rtx reg;
553 rtx mem;
554 rtx pop_rtx;
555 rtx adjust_sp_rtx;
556 rtx parallel_insn;
557 rtx dwarf = NULL_RTX;
559 /* We need to provide a customized rtx which contains
560 necessary information for data analysis,
561 so we create a parallel rtx like this:
562 (parallel [(set (reg:SI Rb)
563 (mem (reg:SI SP_REGNUM)))
564 (set (reg:SI Rb+1)
565 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
567 (set (reg:SI Re)
568 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
569 (set (reg:SI FP_REGNUM)
570 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
571 (set (reg:SI GP_REGNUM)
572 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
573 (set (reg:SI LP_REGNUM)
574 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
575 (set (reg:SI SP_REGNUM)
576 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
578 /* Determine whether we need to restore $fp, $gp, or $lp. */
579 save_fp = INTVAL (En4) & 0x8;
580 save_gp = INTVAL (En4) & 0x4;
581 save_lp = INTVAL (En4) & 0x2;
583 /* Calculate the number of registers that will be poped. */
584 extra_count = 0;
585 if (save_fp)
586 extra_count++;
587 if (save_gp)
588 extra_count++;
589 if (save_lp)
590 extra_count++;
591 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
592 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
593 num_use_regs = extra_count;
594 else
595 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
597 /* In addition to used registers,
598 we need one more space for (set sp sp+x) rtx. */
599 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
600 rtvec_alloc (num_use_regs + 1));
601 par_index = 0;
603 /* Initialize offset and start to create pop behavior. */
604 offset = 0;
606 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
607 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
609 /* Rb and Re may be SP_REGNUM.
610 We need to break this loop immediately. */
611 if (regno == SP_REGNUM)
612 break;
614 reg = gen_rtx_REG (SImode, regno);
615 mem = gen_frame_mem (SImode, plus_constant (Pmode,
616 stack_pointer_rtx,
617 offset));
618 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
619 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
620 RTX_FRAME_RELATED_P (pop_rtx) = 1;
621 offset = offset + 4;
622 par_index++;
624 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
627 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
628 if (save_fp)
630 reg = gen_rtx_REG (SImode, FP_REGNUM);
631 mem = gen_frame_mem (SImode, plus_constant (Pmode,
632 stack_pointer_rtx,
633 offset));
634 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
635 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
636 RTX_FRAME_RELATED_P (pop_rtx) = 1;
637 offset = offset + 4;
638 par_index++;
640 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
642 if (save_gp)
644 reg = gen_rtx_REG (SImode, GP_REGNUM);
645 mem = gen_frame_mem (SImode, plus_constant (Pmode,
646 stack_pointer_rtx,
647 offset));
648 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
649 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
650 RTX_FRAME_RELATED_P (pop_rtx) = 1;
651 offset = offset + 4;
652 par_index++;
654 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
656 if (save_lp)
658 reg = gen_rtx_REG (SImode, LP_REGNUM);
659 mem = gen_frame_mem (SImode, plus_constant (Pmode,
660 stack_pointer_rtx,
661 offset));
662 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
663 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
664 RTX_FRAME_RELATED_P (pop_rtx) = 1;
665 offset = offset + 4;
666 par_index++;
668 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
671 /* Create (set sp sp+x). */
673 /* The offset value is already in place. No need to re-calculate it. */
674 adjust_sp_rtx
675 = gen_rtx_SET (VOIDmode,
676 stack_pointer_rtx,
677 plus_constant (Pmode, stack_pointer_rtx, offset));
678 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
680 /* Tell gcc we adjust SP in this insn. */
681 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
683 parallel_insn = emit_insn (parallel_insn);
685 /* The insn rtx 'parallel_insn' will change frame layout.
686 We need to use RTX_FRAME_RELATED_P so that GCC is able to
687 generate CFI (Call Frame Information) stuff. */
688 RTX_FRAME_RELATED_P (parallel_insn) = 1;
690 /* Add CFI info by manual. */
691 REG_NOTES (parallel_insn) = dwarf;
694 /* Function to create a parallel rtx pattern
695 which presents stack v3push behavior.
696 The overall concept are:
697 "push registers to memory",
698 "adjust stack pointer". */
699 static void
700 nds32_emit_stack_v3push (rtx Rb,
701 rtx Re,
702 rtx En4 ATTRIBUTE_UNUSED,
703 rtx imm8u)
705 int regno;
706 int num_use_regs;
707 int par_index;
708 int offset;
710 rtx reg;
711 rtx mem;
712 rtx push_rtx;
713 rtx adjust_sp_rtx;
714 rtx parallel_insn;
716 /* We need to provide a customized rtx which contains
717 necessary information for data analysis,
718 so we create a parallel rtx like this:
719 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
720 (reg:SI Rb))
721 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
722 (reg:SI Rb+1))
724 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
725 (reg:SI Re))
726 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
727 (reg:SI FP_REGNUM))
728 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
729 (reg:SI GP_REGNUM))
730 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
731 (reg:SI LP_REGNUM))
732 (set (reg:SI SP_REGNUM)
733 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
735 /* Calculate the number of registers that will be pushed.
736 Since $fp, $gp, and $lp is always pushed with v3push instruction,
737 we need to count these three registers.
738 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
739 So there is no need to worry about Rb=Re=SP_REGNUM case. */
740 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
742 /* In addition to used registers,
743 we need one more space for (set sp sp-x-imm8u) rtx. */
744 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
745 rtvec_alloc (num_use_regs + 1));
746 par_index = 0;
748 /* Initialize offset and start to create push behavior. */
749 offset = -(num_use_regs * 4);
751 /* Create (set mem regX) from Rb, Rb+1 up to Re.
752 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
753 So there is no need to worry about Rb=Re=SP_REGNUM case. */
754 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
756 reg = gen_rtx_REG (SImode, regno);
757 mem = gen_frame_mem (SImode, plus_constant (Pmode,
758 stack_pointer_rtx,
759 offset));
760 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
761 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
762 RTX_FRAME_RELATED_P (push_rtx) = 1;
763 offset = offset + 4;
764 par_index++;
767 /* Create (set mem fp). */
768 reg = gen_rtx_REG (SImode, FP_REGNUM);
769 mem = gen_frame_mem (SImode, plus_constant (Pmode,
770 stack_pointer_rtx,
771 offset));
772 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
773 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
774 RTX_FRAME_RELATED_P (push_rtx) = 1;
775 offset = offset + 4;
776 par_index++;
777 /* Create (set mem gp). */
778 reg = gen_rtx_REG (SImode, GP_REGNUM);
779 mem = gen_frame_mem (SImode, plus_constant (Pmode,
780 stack_pointer_rtx,
781 offset));
782 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
783 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
784 RTX_FRAME_RELATED_P (push_rtx) = 1;
785 offset = offset + 4;
786 par_index++;
787 /* Create (set mem lp). */
788 reg = gen_rtx_REG (SImode, LP_REGNUM);
789 mem = gen_frame_mem (SImode, plus_constant (Pmode,
790 stack_pointer_rtx,
791 offset));
792 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
793 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
794 RTX_FRAME_RELATED_P (push_rtx) = 1;
795 offset = offset + 4;
796 par_index++;
798 /* Create (set sp sp-x-imm8u). */
800 /* We need to re-calculate the offset value again for adjustment. */
801 offset = -(num_use_regs * 4);
802 adjust_sp_rtx
803 = gen_rtx_SET (VOIDmode,
804 stack_pointer_rtx,
805 plus_constant (Pmode,
806 stack_pointer_rtx,
807 offset - INTVAL (imm8u)));
808 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
809 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
811 parallel_insn = emit_insn (parallel_insn);
813 /* The insn rtx 'parallel_insn' will change frame layout.
814 We need to use RTX_FRAME_RELATED_P so that GCC is able to
815 generate CFI (Call Frame Information) stuff. */
816 RTX_FRAME_RELATED_P (parallel_insn) = 1;
819 /* Function to create a parallel rtx pattern
820 which presents stack v3pop behavior.
821 The overall concept are:
822 "pop registers from memory",
823 "adjust stack pointer". */
824 static void
825 nds32_emit_stack_v3pop (rtx Rb,
826 rtx Re,
827 rtx En4 ATTRIBUTE_UNUSED,
828 rtx imm8u)
830 int regno;
831 int num_use_regs;
832 int par_index;
833 int offset;
835 rtx reg;
836 rtx mem;
837 rtx pop_rtx;
838 rtx adjust_sp_rtx;
839 rtx parallel_insn;
840 rtx dwarf = NULL_RTX;
842 /* We need to provide a customized rtx which contains
843 necessary information for data analysis,
844 so we create a parallel rtx like this:
845 (parallel [(set (reg:SI Rb)
846 (mem (reg:SI SP_REGNUM)))
847 (set (reg:SI Rb+1)
848 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
850 (set (reg:SI Re)
851 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
852 (set (reg:SI FP_REGNUM)
853 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
854 (set (reg:SI GP_REGNUM)
855 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
856 (set (reg:SI LP_REGNUM)
857 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
858 (set (reg:SI SP_REGNUM)
859 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
861 /* Calculate the number of registers that will be poped.
862 Since $fp, $gp, and $lp is always poped with v3pop instruction,
863 we need to count these three registers.
864 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
865 So there is no need to worry about Rb=Re=SP_REGNUM case. */
866 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
868 /* In addition to used registers,
869 we need one more space for (set sp sp+x+imm8u) rtx. */
870 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
871 rtvec_alloc (num_use_regs + 1));
872 par_index = 0;
874 /* Initialize offset and start to create pop behavior. */
875 offset = 0;
877 /* Create (set regX mem) from Rb, Rb+1 up to Re.
878 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
879 So there is no need to worry about Rb=Re=SP_REGNUM case. */
880 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
882 reg = gen_rtx_REG (SImode, regno);
883 mem = gen_frame_mem (SImode, plus_constant (Pmode,
884 stack_pointer_rtx,
885 offset));
886 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
887 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
888 RTX_FRAME_RELATED_P (pop_rtx) = 1;
889 offset = offset + 4;
890 par_index++;
892 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
895 /* Create (set fp mem). */
896 reg = gen_rtx_REG (SImode, FP_REGNUM);
897 mem = gen_frame_mem (SImode, plus_constant (Pmode,
898 stack_pointer_rtx,
899 offset));
900 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
901 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
902 RTX_FRAME_RELATED_P (pop_rtx) = 1;
903 offset = offset + 4;
904 par_index++;
905 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
907 /* Create (set gp mem). */
908 reg = gen_rtx_REG (SImode, GP_REGNUM);
909 mem = gen_frame_mem (SImode, plus_constant (Pmode,
910 stack_pointer_rtx,
911 offset));
912 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
913 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
914 RTX_FRAME_RELATED_P (pop_rtx) = 1;
915 offset = offset + 4;
916 par_index++;
917 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
919 /* Create (set lp mem ). */
920 reg = gen_rtx_REG (SImode, LP_REGNUM);
921 mem = gen_frame_mem (SImode, plus_constant (Pmode,
922 stack_pointer_rtx,
923 offset));
924 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
925 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
926 RTX_FRAME_RELATED_P (pop_rtx) = 1;
927 offset = offset + 4;
928 par_index++;
929 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
931 /* Create (set sp sp+x+imm8u). */
933 /* The offset value is already in place. No need to re-calculate it. */
934 adjust_sp_rtx
935 = gen_rtx_SET (VOIDmode,
936 stack_pointer_rtx,
937 plus_constant (Pmode,
938 stack_pointer_rtx,
939 offset + INTVAL (imm8u)));
940 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
942 /* Tell gcc we adjust SP in this insn. */
943 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
945 parallel_insn = emit_insn (parallel_insn);
947 /* The insn rtx 'parallel_insn' will change frame layout.
948 We need to use RTX_FRAME_RELATED_P so that GCC is able to
949 generate CFI (Call Frame Information) stuff. */
950 RTX_FRAME_RELATED_P (parallel_insn) = 1;
952 /* Add CFI info by manual. */
953 REG_NOTES (parallel_insn) = dwarf;
956 /* Function that may creates more instructions
957 for large value on adjusting stack pointer.
959 In nds32 target, 'addi' can be used for stack pointer
960 adjustment in prologue/epilogue stage.
961 However, sometimes there are too many local variables so that
962 the adjustment value is not able to be fit in the 'addi' instruction.
963 One solution is to move value into a register
964 and then use 'add' instruction.
965 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
966 Also, we need to return zero for sp adjustment so that
967 proglogue/epilogue knows there is no need to create 'addi' instruction. */
968 static int
969 nds32_force_addi_stack_int (int full_value)
971 int adjust_value;
973 rtx tmp_reg;
974 rtx sp_adjust_insn;
976 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
978 /* The value is not able to fit in single addi instruction.
979 Create more instructions of moving value into a register
980 and then add stack pointer with it. */
982 /* $r15 is going to be temporary register to hold the value. */
983 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
985 /* Create one more instruction to move value
986 into the temporary register. */
987 emit_move_insn (tmp_reg, GEN_INT (full_value));
989 /* Create new 'add' rtx. */
990 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
991 stack_pointer_rtx,
992 tmp_reg);
993 /* Emit rtx into insn list and receive its transformed insn rtx. */
994 sp_adjust_insn = emit_insn (sp_adjust_insn);
996 /* At prologue, we need to tell GCC that this is frame related insn,
997 so that we can consider this instruction to output debug information.
998 If full_value is NEGATIVE, it means this function
999 is invoked by expand_prologue. */
1000 if (full_value < 0)
1002 /* Because (tmp_reg <- full_value) may be split into two
1003 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1004 We need to construct another (sp <- sp + full_value)
1005 and then insert it into sp_adjust_insn's reg note to
1006 represent a frame related expression.
1007 GCC knows how to refer it and output debug information. */
1009 rtx plus_rtx;
1010 rtx set_rtx;
1012 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
1013 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
1014 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
1016 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
1019 /* We have used alternative way to adjust stack pointer value.
1020 Return zero so that prologue/epilogue
1021 will not generate other instructions. */
1022 return 0;
1024 else
1026 /* The value is able to fit in addi instruction.
1027 However, remember to make it to be positive value
1028 because we want to return 'adjustment' result. */
1029 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1031 return adjust_value;
1035 /* Return true if MODE/TYPE need double word alignment. */
1036 static bool
1037 nds32_needs_double_word_align (machine_mode mode, const_tree type)
1039 unsigned int align;
1041 /* Pick up the alignment according to the mode or type. */
1042 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1044 return (align > PARM_BOUNDARY);
1047 /* Return true if FUNC is a naked function. */
1048 static bool
1049 nds32_naked_function_p (tree func)
1051 tree t;
1053 if (TREE_CODE (func) != FUNCTION_DECL)
1054 abort ();
1056 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1058 return (t != NULL_TREE);
1061 /* Function that check if 'X' is a valid address register.
1062 The variable 'STRICT' is very important to
1063 make decision for register number.
1065 STRICT : true
1066 => We are in reload pass or after reload pass.
1067 The register number should be strictly limited in general registers.
1069 STRICT : false
1070 => Before reload pass, we are free to use any register number. */
1071 static bool
1072 nds32_address_register_rtx_p (rtx x, bool strict)
1074 int regno;
1076 if (GET_CODE (x) != REG)
1077 return false;
1079 regno = REGNO (x);
1081 if (strict)
1082 return REGNO_OK_FOR_BASE_P (regno);
1083 else
1084 return true;
1087 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1089 OUTER_MODE : Machine mode of outer address rtx.
1090 INDEX : Check if this rtx is valid to be a index for address.
1091 STRICT : If it is true, we are in reload pass or after reload pass. */
1092 static bool
1093 nds32_legitimate_index_p (machine_mode outer_mode,
1094 rtx index,
1095 bool strict)
1097 int regno;
1098 rtx op0;
1099 rtx op1;
1101 switch (GET_CODE (index))
1103 case REG:
1104 regno = REGNO (index);
1105 /* If we are in reload pass or after reload pass,
1106 we need to limit it to general register. */
1107 if (strict)
1108 return REGNO_OK_FOR_INDEX_P (regno);
1109 else
1110 return true;
1112 case CONST_INT:
1113 /* The alignment of the integer value is determined by 'outer_mode'. */
1114 if (GET_MODE_SIZE (outer_mode) == 1)
1116 /* Further check if the value is legal for the 'outer_mode'. */
1117 if (!satisfies_constraint_Is15 (index))
1118 return false;
1120 /* Pass all test, the value is valid, return true. */
1121 return true;
1123 if (GET_MODE_SIZE (outer_mode) == 2
1124 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1126 /* Further check if the value is legal for the 'outer_mode'. */
1127 if (!satisfies_constraint_Is16 (index))
1128 return false;
1130 /* Pass all test, the value is valid, return true. */
1131 return true;
1133 if (GET_MODE_SIZE (outer_mode) == 4
1134 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1136 /* Further check if the value is legal for the 'outer_mode'. */
1137 if (!satisfies_constraint_Is17 (index))
1138 return false;
1140 /* Pass all test, the value is valid, return true. */
1141 return true;
1143 if (GET_MODE_SIZE (outer_mode) == 8
1144 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1146 /* Further check if the value is legal for the 'outer_mode'. */
1147 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1148 SImode)))
1149 return false;
1151 /* Pass all test, the value is valid, return true. */
1152 return true;
1155 return false;
1157 case MULT:
1158 op0 = XEXP (index, 0);
1159 op1 = XEXP (index, 1);
1161 if (REG_P (op0) && CONST_INT_P (op1))
1163 int multiplier;
1164 multiplier = INTVAL (op1);
1166 /* We only allow (mult reg const_int_1)
1167 or (mult reg const_int_2) or (mult reg const_int_4). */
1168 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1169 return false;
1171 regno = REGNO (op0);
1172 /* Limit it in general registers if we are
1173 in reload pass or after reload pass. */
1174 if(strict)
1175 return REGNO_OK_FOR_INDEX_P (regno);
1176 else
1177 return true;
1180 return false;
1182 case ASHIFT:
1183 op0 = XEXP (index, 0);
1184 op1 = XEXP (index, 1);
1186 if (REG_P (op0) && CONST_INT_P (op1))
1188 int sv;
1189 /* op1 is already the sv value for use to do left shift. */
1190 sv = INTVAL (op1);
1192 /* We only allow (ashift reg const_int_0)
1193 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1194 if (sv != 0 && sv != 1 && sv !=2)
1195 return false;
1197 regno = REGNO (op0);
1198 /* Limit it in general registers if we are
1199 in reload pass or after reload pass. */
1200 if(strict)
1201 return REGNO_OK_FOR_INDEX_P (regno);
1202 else
1203 return true;
1206 return false;
1208 default:
1209 return false;
1213 /* ------------------------------------------------------------------------ */
1215 /* PART 3: Implement target hook stuff definitions. */
1217 /* Register Classes. */
1219 static unsigned char
1220 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1221 machine_mode mode)
1223 /* Return the maximum number of consecutive registers
1224 needed to represent "mode" in a register of "rclass". */
1225 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1228 static int
1229 nds32_register_priority (int hard_regno)
1231 /* Encourage to use r0-r7 for LRA when optimize for size. */
1232 if (optimize_size && hard_regno < 8)
1233 return 4;
1234 return 3;
1238 /* Stack Layout and Calling Conventions. */
1240 /* There are three kinds of pointer concepts using in GCC compiler:
1242 frame pointer: A pointer to the first location of local variables.
1243 stack pointer: A pointer to the top of a stack frame.
1244 argument pointer: A pointer to the incoming arguments.
1246 In nds32 target calling convention, we are using 8-byte alignment.
1247 Besides, we would like to have each stack frame of a function includes:
1249 [Block A]
1250 1. previous hard frame pointer
1251 2. return address
1252 3. callee-saved registers
1253 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1254 and save it at
1255 cfun->machine->callee_saved_area_padding_bytes)
1257 [Block B]
1258 1. local variables
1259 2. spilling location
1260 3. <padding bytes> (it will be calculated by GCC itself)
1261 4. incoming arguments
1262 5. <padding bytes> (it will be calculated by GCC itself)
1264 [Block C]
1265 1. <padding bytes> (it will be calculated by GCC itself)
1266 2. outgoing arguments
1268 We 'wrap' these blocks together with
1269 hard frame pointer ($r28) and stack pointer ($r31).
1270 By applying the basic frame/stack/argument pointers concept,
1271 the layout of a stack frame shoule be like this:
1274 old stack pointer -> ----
1275 | | \
1276 | | saved arguments for
1277 | | vararg functions
1278 | | /
1279 hard frame pointer -> --
1280 & argument pointer | | \
1281 | | previous hardware frame pointer
1282 | | return address
1283 | | callee-saved registers
1284 | | /
1285 frame pointer -> --
1286 | | \
1287 | | local variables
1288 | | and incoming arguments
1289 | | /
1291 | | \
1292 | | outgoing
1293 | | arguments
1294 | | /
1295 stack pointer -> ----
1297 $SFP and $AP are used to represent frame pointer and arguments pointer,
1298 which will be both eliminated as hard frame pointer. */
1300 /* -- Eliminating Frame Pointer and Arg Pointer. */
1302 static bool
1303 nds32_can_eliminate (const int from_reg, const int to_reg)
1305 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1306 return true;
1308 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1309 return true;
1311 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1312 return true;
1314 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1315 return true;
1317 return false;
1320 /* -- Passing Arguments in Registers. */
1322 static rtx
1323 nds32_function_arg (cumulative_args_t ca, machine_mode mode,
1324 const_tree type, bool named)
1326 unsigned int regno;
1327 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1329 /* The last time this hook is called,
1330 it is called with MODE == VOIDmode. */
1331 if (mode == VOIDmode)
1332 return NULL_RTX;
1334 /* For nameless arguments, we need to take care it individually. */
1335 if (!named)
1337 /* If we are under hard float abi, we have arguments passed on the
1338 stack and all situation can be handled by GCC itself. */
1339 if (TARGET_HARD_FLOAT)
1340 return NULL_RTX;
1342 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1344 /* If we still have enough registers to pass argument, pick up
1345 next available register number. */
1346 regno
1347 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1348 return gen_rtx_REG (mode, regno);
1351 /* No register available, return NULL_RTX.
1352 The compiler will use stack to pass argument instead. */
1353 return NULL_RTX;
1356 /* The following is to handle named argument.
1357 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1358 are different. */
1359 if (TARGET_HARD_FLOAT)
1361 /* Currently we have not implemented hard float yet. */
1362 gcc_unreachable ();
1364 else
1366 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1367 argument. Since we allow to pass argument partially in registers,
1368 we can just return it if there are still registers available. */
1369 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1371 /* Pick up the next available register number. */
1372 regno
1373 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1374 return gen_rtx_REG (mode, regno);
1379 /* No register available, return NULL_RTX.
1380 The compiler will use stack to pass argument instead. */
1381 return NULL_RTX;
1384 static bool
1385 nds32_must_pass_in_stack (machine_mode mode, const_tree type)
1387 /* Return true if a type must be passed in memory.
1388 If it is NOT using hard float abi, small aggregates can be
1389 passed in a register even we are calling a variadic function.
1390 So there is no need to take padding into consideration. */
1391 if (TARGET_HARD_FLOAT)
1392 return must_pass_in_stack_var_size_or_pad (mode, type);
1393 else
1394 return must_pass_in_stack_var_size (mode, type);
1397 static int
1398 nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
1399 tree type, bool named ATTRIBUTE_UNUSED)
1401 /* Returns the number of bytes at the beginning of an argument that
1402 must be put in registers. The value must be zero for arguments that are
1403 passed entirely in registers or that are entirely pushed on the stack.
1404 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1405 first register to be used by the caller for this argument. */
1406 unsigned int needed_reg_count;
1407 unsigned int remaining_reg_count;
1408 CUMULATIVE_ARGS *cum;
1410 cum = get_cumulative_args (ca);
1412 /* Under hard float abi, we better have argument entirely passed in
1413 registers or pushed on the stack so that we can reduce the complexity
1414 of dealing with cum->gpr_offset and cum->fpr_offset. */
1415 if (TARGET_HARD_FLOAT)
1416 return 0;
1418 /* If we have already runned out of argument registers, return zero
1419 so that the argument will be entirely pushed on the stack. */
1420 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1421 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1422 return 0;
1424 /* Calculate how many registers do we need for this argument. */
1425 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1427 /* Calculate how many argument registers have left for passing argument.
1428 Note that we should count it from next available register number. */
1429 remaining_reg_count
1430 = NDS32_MAX_GPR_REGS_FOR_ARGS
1431 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1432 - NDS32_GPR_ARG_FIRST_REGNUM);
1434 /* Note that we have to return the nubmer of bytes, not registers count. */
1435 if (needed_reg_count > remaining_reg_count)
1436 return remaining_reg_count * UNITS_PER_WORD;
1438 return 0;
1441 static void
1442 nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
1443 const_tree type, bool named)
1445 machine_mode sub_mode;
1446 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1448 if (named)
1450 /* We need to further check TYPE and MODE so that we can determine
1451 which kind of register we shall advance. */
1452 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1453 sub_mode = TYPE_MODE (TREE_TYPE (type));
1454 else
1455 sub_mode = mode;
1457 /* Under hard float abi, we may advance FPR registers. */
1458 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1460 /* Currently we have not implemented hard float yet. */
1461 gcc_unreachable ();
1463 else
1465 cum->gpr_offset
1466 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1467 - NDS32_GPR_ARG_FIRST_REGNUM
1468 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1471 else
1473 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1474 we can advance next register as well so that caller is
1475 able to pass arguments in registers and callee must be
1476 in charge of pushing all of them into stack. */
1477 if (!TARGET_HARD_FLOAT)
1479 cum->gpr_offset
1480 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1481 - NDS32_GPR_ARG_FIRST_REGNUM
1482 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1487 static unsigned int
1488 nds32_function_arg_boundary (machine_mode mode, const_tree type)
1490 return (nds32_needs_double_word_align (mode, type)
1491 ? NDS32_DOUBLE_WORD_ALIGNMENT
1492 : PARM_BOUNDARY);
1495 /* -- How Scalar Function Values Are Returned. */
1497 static rtx
1498 nds32_function_value (const_tree ret_type,
1499 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1500 bool outgoing ATTRIBUTE_UNUSED)
1502 machine_mode mode;
1503 int unsignedp;
1505 mode = TYPE_MODE (ret_type);
1506 unsignedp = TYPE_UNSIGNED (ret_type);
1508 mode = promote_mode (ret_type, mode, &unsignedp);
1510 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1513 static rtx
1514 nds32_libcall_value (machine_mode mode,
1515 const_rtx fun ATTRIBUTE_UNUSED)
1517 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1520 static bool
1521 nds32_function_value_regno_p (const unsigned int regno)
1523 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1526 /* -- Function Entry and Exit. */
1528 /* The content produced from this function
1529 will be placed before prologue body. */
1530 static void
1531 nds32_asm_function_prologue (FILE *file,
1532 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1534 int r;
1535 const char *func_name;
1536 tree attrs;
1537 tree name;
1539 /* All stack frame information is supposed to be
1540 already computed when expanding prologue.
1541 The result is in cfun->machine.
1542 DO NOT call nds32_compute_stack_frame() here
1543 because it may corrupt the essential information. */
1545 fprintf (file, "\t! BEGIN PROLOGUE\n");
1546 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1547 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1548 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1549 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1551 /* Use df_regs_ever_live_p() to detect if the register
1552 is ever used in the current function. */
1553 fprintf (file, "\t! registers ever_live: ");
1554 for (r = 0; r < 32; r++)
1556 if (df_regs_ever_live_p (r))
1557 fprintf (file, "%s, ", reg_names[r]);
1559 fputc ('\n', file);
1561 /* Display the attributes of this function. */
1562 fprintf (file, "\t! function attributes: ");
1563 /* Get the attributes tree list.
1564 Note that GCC builds attributes list with reverse order. */
1565 attrs = DECL_ATTRIBUTES (current_function_decl);
1567 /* If there is no any attribute, print out "None". */
1568 if (!attrs)
1569 fprintf (file, "None");
1571 /* If there are some attributes, try if we need to
1572 construct isr vector information. */
1573 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1574 nds32_construct_isr_vectors_information (attrs, func_name);
1576 /* Display all attributes of this function. */
1577 while (attrs)
1579 name = TREE_PURPOSE (attrs);
1580 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1582 /* Pick up the next attribute. */
1583 attrs = TREE_CHAIN (attrs);
1585 fputc ('\n', file);
1588 /* After rtl prologue has been expanded, this function is used. */
1589 static void
1590 nds32_asm_function_end_prologue (FILE *file)
1592 fprintf (file, "\t! END PROLOGUE\n");
1594 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1595 we can generate special directive: ".omit_fp_begin"
1596 to guide linker doing fp-as-gp optimization.
1597 However, for a naked function, which means
1598 it should not have prologue/epilogue,
1599 using fp-as-gp still requires saving $fp by push/pop behavior and
1600 there is no benefit to use fp-as-gp on such small function.
1601 So we need to make sure this function is NOT naked as well. */
1602 if (!frame_pointer_needed
1603 && !cfun->machine->naked_p
1604 && cfun->machine->fp_as_gp_p)
1606 fprintf (file, "\t! ----------------------------------------\n");
1607 fprintf (file, "\t! Guide linker to do "
1608 "link time optimization: fp-as-gp\n");
1609 fprintf (file, "\t! We add one more instruction to "
1610 "initialize $fp near to $gp location.\n");
1611 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1612 fprintf (file, "\t! this extra instruction should be "
1613 "eliminated at link stage.\n");
1614 fprintf (file, "\t.omit_fp_begin\n");
1615 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1616 fprintf (file, "\t! ----------------------------------------\n");
1620 /* Before rtl epilogue has been expanded, this function is used. */
1621 static void
1622 nds32_asm_function_begin_epilogue (FILE *file)
1624 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1625 we can generate special directive: ".omit_fp_end"
1626 to claim fp-as-gp optimization range.
1627 However, for a naked function,
1628 which means it should not have prologue/epilogue,
1629 using fp-as-gp still requires saving $fp by push/pop behavior and
1630 there is no benefit to use fp-as-gp on such small function.
1631 So we need to make sure this function is NOT naked as well. */
1632 if (!frame_pointer_needed
1633 && !cfun->machine->naked_p
1634 && cfun->machine->fp_as_gp_p)
1636 fprintf (file, "\t! ----------------------------------------\n");
1637 fprintf (file, "\t! Claim the range of fp-as-gp "
1638 "link time optimization\n");
1639 fprintf (file, "\t.omit_fp_end\n");
1640 fprintf (file, "\t! ----------------------------------------\n");
1643 fprintf (file, "\t! BEGIN EPILOGUE\n");
1646 /* The content produced from this function
1647 will be placed after epilogue body. */
1648 static void
1649 nds32_asm_function_epilogue (FILE *file,
1650 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1652 fprintf (file, "\t! END EPILOGUE\n");
1655 static void
1656 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1657 HOST_WIDE_INT delta,
1658 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1659 tree function)
1661 int this_regno;
1663 /* Make sure unwind info is emitted for the thunk if needed. */
1664 final_start_function (emit_barrier (), file, 1);
1666 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1668 : 0);
1670 if (delta != 0)
1672 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1674 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1675 this_regno, this_regno, delta);
1677 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1679 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1680 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1682 else
1684 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1685 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1686 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1690 fprintf (file, "\tb\t");
1691 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1692 fprintf (file, "\n");
1694 final_end_function ();
1697 /* -- Permitting tail calls. */
1699 /* Determine whether we need to enable warning for function return check. */
1700 static bool
1701 nds32_warn_func_return (tree decl)
1703 /* Naked functions are implemented entirely in assembly, including the
1704 return sequence, so suppress warnings about this. */
1705 return !nds32_naked_function_p (decl);
1709 /* Implementing the Varargs Macros. */
1711 static void
1712 nds32_setup_incoming_varargs (cumulative_args_t ca,
1713 machine_mode mode,
1714 tree type,
1715 int *pretend_args_size,
1716 int second_time ATTRIBUTE_UNUSED)
1718 unsigned int total_args_regs;
1719 unsigned int num_of_used_regs;
1720 unsigned int remaining_reg_count;
1721 CUMULATIVE_ARGS *cum;
1723 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1724 So that all nameless arguments are pushed by caller and all situation
1725 can be handled by GCC itself. */
1726 if (TARGET_HARD_FLOAT)
1727 return;
1729 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1730 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1731 However, for nameless(anonymous) arguments, we should push them on the
1732 stack so that all the nameless arguments appear to have been passed
1733 consecutively in the memory for accessing. Hence, we need to check and
1734 exclude the registers that are used for named arguments. */
1736 cum = get_cumulative_args (ca);
1738 /* The MODE and TYPE describe the last argument.
1739 We need those information to determine the remaining registers
1740 for varargs. */
1741 total_args_regs
1742 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1743 num_of_used_regs
1744 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1745 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1747 remaining_reg_count = total_args_regs - num_of_used_regs;
1748 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1750 return;
1753 static bool
1754 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1756 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1757 true for named arguments, and false for unnamed arguments. */
1758 return true;
1762 /* Trampolines for Nested Functions. */
1764 static void
1765 nds32_asm_trampoline_template (FILE *f)
1767 if (TARGET_REDUCED_REGS)
1769 /* Trampoline is not supported on reduced-set registers yet. */
1770 sorry ("a nested function is not supported for reduced registers");
1772 else
1774 asm_fprintf (f, "\t! Trampoline code template\n");
1775 asm_fprintf (f, "\t! This code fragment will be copied "
1776 "into stack on demand\n");
1778 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1779 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1780 "! load nested function address\n");
1781 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1782 "! load chain_value\n");
1783 asm_fprintf (f, "\tjr\t$r15\n");
1786 /* Preserve space ($pc + 16) for saving chain_value,
1787 nds32_trampoline_init will fill the value in this slot. */
1788 asm_fprintf (f, "\t! space for saving chain_value\n");
1789 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1791 /* Preserve space ($pc + 20) for saving nested function address,
1792 nds32_trampoline_init will fill the value in this slot. */
1793 asm_fprintf (f, "\t! space for saving nested function address\n");
1794 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1797 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1798 static void
1799 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1801 int i;
1803 /* Nested function address. */
1804 rtx fnaddr;
1805 /* The memory rtx that is going to
1806 be filled with chain_value. */
1807 rtx chain_value_mem;
1808 /* The memory rtx that is going to
1809 be filled with nested function address. */
1810 rtx nested_func_mem;
1812 /* Start address of trampoline code in stack, for doing cache sync. */
1813 rtx sync_cache_addr;
1814 /* Temporary register for sync instruction. */
1815 rtx tmp_reg;
1816 /* Instruction-cache sync instruction,
1817 requesting an argument as starting address. */
1818 rtx isync_insn;
1819 /* For convenience reason of doing comparison. */
1820 int tramp_align_in_bytes;
1822 /* Trampoline is not supported on reduced-set registers yet. */
1823 if (TARGET_REDUCED_REGS)
1824 sorry ("a nested function is not supported for reduced registers");
1826 /* STEP 1: Copy trampoline code template into stack,
1827 fill up essential data into stack. */
1829 /* Extract nested function address rtx. */
1830 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1832 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1833 We have nds32_asm_trampoline_template() to emit template pattern. */
1834 emit_block_move (m_tramp, assemble_trampoline_template (),
1835 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1837 /* After copying trampoline code into stack,
1838 fill chain_value into stack. */
1839 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1840 emit_move_insn (chain_value_mem, chain_value);
1841 /* After copying trampoline code int stack,
1842 fill nested function address into stack. */
1843 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1844 emit_move_insn (nested_func_mem, fnaddr);
1846 /* STEP 2: Sync instruction-cache. */
1848 /* We have successfully filled trampoline code into stack.
1849 However, in order to execute code in stack correctly,
1850 we must sync instruction cache. */
1851 sync_cache_addr = XEXP (m_tramp, 0);
1852 tmp_reg = gen_reg_rtx (SImode);
1853 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1855 /* Because nds32_cache_block_size is in bytes,
1856 we get trampoline alignment in bytes for convenient comparison. */
1857 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1859 if (tramp_align_in_bytes >= nds32_cache_block_size
1860 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1862 /* Under this condition, the starting address of trampoline
1863 must be aligned to the starting address of each cache block
1864 and we do not have to worry about cross-boundary issue. */
1865 for (i = 0;
1866 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1867 / nds32_cache_block_size;
1868 i++)
1870 emit_move_insn (tmp_reg,
1871 plus_constant (Pmode, sync_cache_addr,
1872 nds32_cache_block_size * i));
1873 emit_insn (isync_insn);
1876 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1878 /* The starting address of trampoline code
1879 may not be aligned to the cache block,
1880 so the trampoline code may be across two cache block.
1881 We need to sync the last element, which is 4-byte size,
1882 of trampoline template. */
1883 for (i = 0;
1884 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1885 / nds32_cache_block_size;
1886 i++)
1888 emit_move_insn (tmp_reg,
1889 plus_constant (Pmode, sync_cache_addr,
1890 nds32_cache_block_size * i));
1891 emit_insn (isync_insn);
1894 /* The last element of trampoline template is 4-byte size. */
1895 emit_move_insn (tmp_reg,
1896 plus_constant (Pmode, sync_cache_addr,
1897 TRAMPOLINE_SIZE - 4));
1898 emit_insn (isync_insn);
1900 else
1902 /* This is the simplest case.
1903 Because TRAMPOLINE_SIZE is less than or
1904 equal to nds32_cache_block_size,
1905 we can just sync start address and
1906 the last element of trampoline code. */
1908 /* Sync starting address of tampoline code. */
1909 emit_move_insn (tmp_reg, sync_cache_addr);
1910 emit_insn (isync_insn);
1911 /* Sync the last element, which is 4-byte size,
1912 of trampoline template. */
1913 emit_move_insn (tmp_reg,
1914 plus_constant (Pmode, sync_cache_addr,
1915 TRAMPOLINE_SIZE - 4));
1916 emit_insn (isync_insn);
1919 /* Set instruction serialization barrier
1920 to guarantee the correct operations. */
1921 emit_insn (gen_unspec_volatile_isb ());
1925 /* Addressing Modes. */
1927 static bool
1928 nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1930 /* For (mem:DI addr) or (mem:DF addr) case,
1931 we only allow 'addr' to be [reg], [symbol_ref],
1932 [const], or [reg + const_int] pattern. */
1933 if (mode == DImode || mode == DFmode)
1935 /* Allow [Reg + const_int] addressing mode. */
1936 if (GET_CODE (x) == PLUS)
1938 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1939 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1940 && CONST_INT_P (XEXP (x, 1)))
1941 return true;
1943 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1944 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1945 && CONST_INT_P (XEXP (x, 0)))
1946 return true;
1949 /* Now check [reg], [symbol_ref], and [const]. */
1950 if (GET_CODE (x) != REG
1951 && GET_CODE (x) != SYMBOL_REF
1952 && GET_CODE (x) != CONST)
1953 return false;
1956 /* Check if 'x' is a valid address. */
1957 switch (GET_CODE (x))
1959 case REG:
1960 /* (mem (reg A)) => [Ra] */
1961 return nds32_address_register_rtx_p (x, strict);
1963 case SYMBOL_REF:
1965 if (!TARGET_GP_DIRECT
1966 && (reload_completed
1967 || reload_in_progress
1968 || lra_in_progress))
1969 return false;
1971 /* (mem (symbol_ref A)) => [symbol_ref] */
1972 return !currently_expanding_to_rtl;
1974 case CONST:
1976 if (!TARGET_GP_DIRECT
1977 && (reload_completed
1978 || reload_in_progress
1979 || lra_in_progress))
1980 return false;
1982 /* (mem (const (...)))
1983 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1984 if (GET_CODE (XEXP (x, 0)) == PLUS)
1986 rtx plus_op = XEXP (x, 0);
1988 rtx op0 = XEXP (plus_op, 0);
1989 rtx op1 = XEXP (plus_op, 1);
1991 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1992 return true;
1993 else
1994 return false;
1997 return false;
1999 case POST_MODIFY:
2000 /* (mem (post_modify (reg) (plus (reg) (reg))))
2001 => [Ra], Rb */
2002 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2003 => [Ra], const_int */
2004 if (GET_CODE (XEXP (x, 0)) == REG
2005 && GET_CODE (XEXP (x, 1)) == PLUS)
2007 rtx plus_op = XEXP (x, 1);
2009 rtx op0 = XEXP (plus_op, 0);
2010 rtx op1 = XEXP (plus_op, 1);
2012 if (nds32_address_register_rtx_p (op0, strict)
2013 && nds32_legitimate_index_p (mode, op1, strict))
2014 return true;
2015 else
2016 return false;
2019 return false;
2021 case POST_INC:
2022 case POST_DEC:
2023 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2024 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2025 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2026 We only need to deal with register Ra. */
2027 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2028 return true;
2029 else
2030 return false;
2032 case PLUS:
2033 /* (mem (plus reg const_int))
2034 => [Ra + imm] */
2035 /* (mem (plus reg reg))
2036 => [Ra + Rb] */
2037 /* (mem (plus (mult reg const_int) reg))
2038 => [Ra + Rb << sv] */
2039 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2040 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2041 return true;
2042 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2043 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2044 return true;
2045 else
2046 return false;
2048 case LO_SUM:
2049 /* (mem (lo_sum (reg) (symbol_ref))) */
2050 /* (mem (lo_sum (reg) (const))) */
2051 gcc_assert (REG_P (XEXP (x, 0)));
2052 if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
2053 || GET_CODE (XEXP (x, 1)) == CONST)
2054 return nds32_legitimate_address_p (mode, XEXP (x, 1), strict);
2055 else
2056 return false;
2058 default:
2059 return false;
2064 /* Describing Relative Costs of Operations. */
2066 static int
2067 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2068 reg_class_t from,
2069 reg_class_t to)
2071 if (from == HIGH_REGS || to == HIGH_REGS)
2072 return 6;
2074 return 2;
2077 static int
2078 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2079 reg_class_t rclass ATTRIBUTE_UNUSED,
2080 bool in ATTRIBUTE_UNUSED)
2082 return 8;
2085 /* This target hook describes the relative costs of RTL expressions.
2086 Return 'true' when all subexpressions of x have been processed.
2087 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2088 Refer to gcc/rtlanal.c for more information. */
2089 static bool
2090 nds32_rtx_costs (rtx x,
2091 int code,
2092 int outer_code,
2093 int opno,
2094 int *total,
2095 bool speed)
2097 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
2100 static int
2101 nds32_address_cost (rtx address,
2102 machine_mode mode,
2103 addr_space_t as,
2104 bool speed)
2106 return nds32_address_cost_impl (address, mode, as, speed);
2110 /* Defining the Output Assembler Language. */
2112 /* -- The Overall Framework of an Assembler File. */
2114 static void
2115 nds32_asm_file_start (void)
2117 default_file_start ();
2119 /* Tell assembler which ABI we are using. */
2120 fprintf (asm_out_file, "\t! ABI version\n");
2121 fprintf (asm_out_file, "\t.abi_2\n");
2123 /* Tell assembler that this asm code is generated by compiler. */
2124 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2125 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2126 /* Give assembler the size of each vector for interrupt handler. */
2127 fprintf (asm_out_file, "\t! This vector size directive is required "
2128 "for checking inconsistency on interrupt handler\n");
2129 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2131 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2132 the compiler may produce 'la $fp,_FP_BASE_' instruction
2133 at prologue for fp-as-gp optimization.
2134 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2135 in case user does not pass '--relax' option to linker. */
2136 if (TARGET_FORCE_FP_AS_GP || optimize_size)
2138 fprintf (asm_out_file, "\t! This weak reference is required to do "
2139 "fp-as-gp link time optimization\n");
2140 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
2142 /* If user enables '-mex9', we should emit relaxation directive
2143 to tell linker that this file is allowed to do ex9 optimization. */
2144 if (TARGET_EX9)
2146 fprintf (asm_out_file, "\t! This relaxation directive is required "
2147 "to do ex9 link time optimization\n");
2148 fprintf (asm_out_file, "\t.relax\tex9\n");
2151 fprintf (asm_out_file, "\t! ------------------------------------\n");
2153 if (TARGET_ISA_V2)
2154 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2155 if (TARGET_ISA_V3)
2156 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2157 if (TARGET_ISA_V3M)
2158 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2160 if (TARGET_CMODEL_SMALL)
2161 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL");
2162 if (TARGET_CMODEL_MEDIUM)
2163 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "MEDIUM");
2164 if (TARGET_CMODEL_LARGE)
2165 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "LARGE");
2167 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2168 ((TARGET_BIG_ENDIAN) ? "big-endian"
2169 : "little-endian"));
2171 fprintf (asm_out_file, "\t! ------------------------------------\n");
2173 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2174 ((TARGET_CMOV) ? "Yes"
2175 : "No"));
2176 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2177 ((TARGET_PERF_EXT) ? "Yes"
2178 : "No"));
2180 fprintf (asm_out_file, "\t! ------------------------------------\n");
2182 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2183 ((TARGET_V3PUSH) ? "Yes"
2184 : "No"));
2185 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2186 ((TARGET_16_BIT) ? "Yes"
2187 : "No"));
2188 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2189 ((TARGET_REDUCED_REGS) ? "Yes"
2190 : "No"));
2192 fprintf (asm_out_file, "\t! ------------------------------------\n");
2194 if (optimize_size)
2195 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2196 else
2197 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2199 fprintf (asm_out_file, "\t! ------------------------------------\n");
2201 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2202 nds32_cache_block_size);
2204 fprintf (asm_out_file, "\t! ------------------------------------\n");
2206 nds32_asm_file_start_for_isr ();
2209 static void
2210 nds32_asm_file_end (void)
2212 nds32_asm_file_end_for_isr ();
2214 fprintf (asm_out_file, "\t! ------------------------------------\n");
2217 /* -- Output and Generation of Labels. */
2219 static void
2220 nds32_asm_globalize_label (FILE *stream, const char *name)
2222 fputs ("\t.global\t", stream);
2223 assemble_name (stream, name);
2224 fputs ("\n", stream);
2227 /* -- Output of Assembler Instructions. */
2229 static void
2230 nds32_print_operand (FILE *stream, rtx x, int code)
2232 int op_value;
2234 switch (code)
2236 case 0 :
2237 /* Do nothing special. */
2238 break;
2240 case 'V':
2241 /* 'x' is supposed to be CONST_INT, get the value. */
2242 gcc_assert (CONST_INT_P (x));
2243 op_value = INTVAL (x);
2245 /* According to the Andes architecture,
2246 the system/user register index range is 0 ~ 1023.
2247 In order to avoid conflict between user-specified-integer value
2248 and enum-specified-register value,
2249 the 'enum nds32_intrinsic_registers' value
2250 in nds32_intrinsic.h starts from 1024. */
2251 if (op_value < 1024 && op_value >= 0)
2253 /* If user gives integer value directly (0~1023),
2254 we just print out the value. */
2255 fprintf (stream, "%d", op_value);
2257 else if (op_value < 0
2258 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2259 + 1024))
2261 /* The enum index value for array size is out of range. */
2262 error ("intrinsic register index is out of range");
2264 else
2266 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2267 we can print out register name. Remember to substract 1024. */
2268 fprintf (stream, "%s",
2269 nds32_intrinsic_register_names[op_value - 1024]);
2272 /* No need to handle following process, so return immediately. */
2273 return;
2275 default :
2276 /* Unknown flag. */
2277 output_operand_lossage ("invalid operand output code");
2278 break;
2281 switch (GET_CODE (x))
2283 case LABEL_REF:
2284 case SYMBOL_REF:
2285 output_addr_const (stream, x);
2286 break;
2288 case REG:
2289 /* Forbid using static chain register ($r16)
2290 on reduced-set registers configuration. */
2291 if (TARGET_REDUCED_REGS
2292 && REGNO (x) == STATIC_CHAIN_REGNUM)
2293 sorry ("a nested function is not supported for reduced registers");
2295 /* Normal cases, print out register name. */
2296 fputs (reg_names[REGNO (x)], stream);
2297 break;
2299 case MEM:
2300 output_address (XEXP (x, 0));
2301 break;
2303 case CODE_LABEL:
2304 case CONST_INT:
2305 case CONST:
2306 output_addr_const (stream, x);
2307 break;
2309 default:
2310 /* Generally, output_addr_const () is able to handle most cases.
2311 We want to see what CODE could appear,
2312 so we use gcc_unreachable() to stop it. */
2313 debug_rtx (x);
2314 gcc_unreachable ();
2315 break;
2319 static void
2320 nds32_print_operand_address (FILE *stream, rtx x)
2322 rtx op0, op1;
2324 switch (GET_CODE (x))
2326 case SYMBOL_REF:
2327 case CONST:
2328 /* [ + symbol_ref] */
2329 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2330 fputs ("[ + ", stream);
2331 output_addr_const (stream, x);
2332 fputs ("]", stream);
2333 break;
2335 case REG:
2336 /* Forbid using static chain register ($r16)
2337 on reduced-set registers configuration. */
2338 if (TARGET_REDUCED_REGS
2339 && REGNO (x) == STATIC_CHAIN_REGNUM)
2340 sorry ("a nested function is not supported for reduced registers");
2342 /* [Ra] */
2343 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2344 break;
2346 case PLUS:
2347 op0 = XEXP (x, 0);
2348 op1 = XEXP (x, 1);
2350 /* Checking op0, forbid using static chain register ($r16)
2351 on reduced-set registers configuration. */
2352 if (TARGET_REDUCED_REGS
2353 && REG_P (op0)
2354 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2355 sorry ("a nested function is not supported for reduced registers");
2356 /* Checking op1, forbid using static chain register ($r16)
2357 on reduced-set registers configuration. */
2358 if (TARGET_REDUCED_REGS
2359 && REG_P (op1)
2360 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2361 sorry ("a nested function is not supported for reduced registers");
2363 if (REG_P (op0) && CONST_INT_P (op1))
2365 /* [Ra + imm] */
2366 fprintf (stream, "[%s + (%d)]",
2367 reg_names[REGNO (op0)], (int)INTVAL (op1));
2369 else if (REG_P (op0) && REG_P (op1))
2371 /* [Ra + Rb] */
2372 fprintf (stream, "[%s + %s]",
2373 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2375 else if (GET_CODE (op0) == MULT && REG_P (op1))
2377 /* [Ra + Rb << sv]
2378 From observation, the pattern looks like:
2379 (plus:SI (mult:SI (reg:SI 58)
2380 (const_int 4 [0x4]))
2381 (reg/f:SI 57)) */
2382 int sv;
2384 /* We need to set sv to output shift value. */
2385 if (INTVAL (XEXP (op0, 1)) == 1)
2386 sv = 0;
2387 else if (INTVAL (XEXP (op0, 1)) == 2)
2388 sv = 1;
2389 else if (INTVAL (XEXP (op0, 1)) == 4)
2390 sv = 2;
2391 else
2392 gcc_unreachable ();
2394 fprintf (stream, "[%s + %s << %d]",
2395 reg_names[REGNO (op1)],
2396 reg_names[REGNO (XEXP (op0, 0))],
2397 sv);
2399 else
2401 /* The control flow is not supposed to be here. */
2402 debug_rtx (x);
2403 gcc_unreachable ();
2406 break;
2408 case POST_MODIFY:
2409 /* (post_modify (regA) (plus (regA) (regB)))
2410 (post_modify (regA) (plus (regA) (const_int)))
2411 We would like to extract
2412 regA and regB (or const_int) from plus rtx. */
2413 op0 = XEXP (XEXP (x, 1), 0);
2414 op1 = XEXP (XEXP (x, 1), 1);
2416 /* Checking op0, forbid using static chain register ($r16)
2417 on reduced-set registers configuration. */
2418 if (TARGET_REDUCED_REGS
2419 && REG_P (op0)
2420 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2421 sorry ("a nested function is not supported for reduced registers");
2422 /* Checking op1, forbid using static chain register ($r16)
2423 on reduced-set registers configuration. */
2424 if (TARGET_REDUCED_REGS
2425 && REG_P (op1)
2426 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2427 sorry ("a nested function is not supported for reduced registers");
2429 if (REG_P (op0) && REG_P (op1))
2431 /* [Ra], Rb */
2432 fprintf (stream, "[%s], %s",
2433 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2435 else if (REG_P (op0) && CONST_INT_P (op1))
2437 /* [Ra], imm */
2438 fprintf (stream, "[%s], %d",
2439 reg_names[REGNO (op0)], (int)INTVAL (op1));
2441 else
2443 /* The control flow is not supposed to be here. */
2444 debug_rtx (x);
2445 gcc_unreachable ();
2448 break;
2450 case POST_INC:
2451 case POST_DEC:
2452 op0 = XEXP (x, 0);
2454 /* Checking op0, forbid using static chain register ($r16)
2455 on reduced-set registers configuration. */
2456 if (TARGET_REDUCED_REGS
2457 && REG_P (op0)
2458 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2459 sorry ("a nested function is not supported for reduced registers");
2461 if (REG_P (op0))
2463 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2464 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2465 We only need to deal with register Ra. */
2466 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2468 else
2470 /* The control flow is not supposed to be here. */
2471 debug_rtx (x);
2472 gcc_unreachable ();
2475 break;
2477 default :
2478 /* Generally, output_addr_const () is able to handle most cases.
2479 We want to see what CODE could appear,
2480 so we use gcc_unreachable() to stop it. */
2481 debug_rtx (x);
2482 gcc_unreachable ();
2483 break;
2488 /* Defining target-specific uses of __attribute__. */
2490 /* Add some checking after merging attributes. */
2491 static tree
2492 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2494 tree combined_attrs;
2496 /* Create combined attributes. */
2497 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2498 DECL_ATTRIBUTES (newdecl));
2500 /* Since newdecl is acutally a duplicate of olddecl,
2501 we can take olddecl for some operations. */
2502 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2504 /* Check isr-specific attributes conflict. */
2505 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2508 return combined_attrs;
2511 /* Add some checking when inserting attributes. */
2512 static void
2513 nds32_insert_attributes (tree decl, tree *attributes)
2515 /* For function declaration, we need to check isr-specific attributes:
2516 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2517 2. Check valid integer value for interrupt/exception.
2518 3. Check valid integer value for reset.
2519 4. Check valid function for nmi/warm. */
2520 if (TREE_CODE (decl) == FUNCTION_DECL)
2522 tree func_attrs;
2523 tree intr, excp, reset;
2525 /* Pick up function attributes. */
2526 func_attrs = *attributes;
2528 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2529 nds32_check_isr_attrs_conflict (decl, func_attrs);
2531 /* Now we are starting to check valid id value
2532 for interrupt/exception/reset.
2533 Note that we ONLY check its validity here.
2534 To construct isr vector information, it is still performed
2535 by nds32_construct_isr_vectors_information(). */
2536 intr = lookup_attribute ("interrupt", func_attrs);
2537 excp = lookup_attribute ("exception", func_attrs);
2538 reset = lookup_attribute ("reset", func_attrs);
2540 if (intr || excp)
2542 /* Deal with interrupt/exception. */
2543 tree id_list;
2544 unsigned int lower_bound, upper_bound;
2546 /* The way to handle interrupt or exception is the same,
2547 we just need to take care of actual vector number.
2548 For interrupt(0..63), the actual vector number is (9..72).
2549 For exception(1..8), the actual vector number is (1..8). */
2550 lower_bound = (intr) ? (0) : (1);
2551 upper_bound = (intr) ? (63) : (8);
2553 /* Prepare id list so that we can traverse id value. */
2554 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2556 /* 2. Check valid integer value for interrupt/exception. */
2557 while (id_list)
2559 tree id;
2561 /* Pick up each vector id value. */
2562 id = TREE_VALUE (id_list);
2563 /* Issue error if it is not a valid integer value. */
2564 if (TREE_CODE (id) != INTEGER_CST
2565 || wi::ltu_p (id, lower_bound)
2566 || wi::gtu_p (id, upper_bound))
2567 error ("invalid id value for interrupt/exception attribute");
2569 /* Advance to next id. */
2570 id_list = TREE_CHAIN (id_list);
2573 else if (reset)
2575 /* Deal with reset. */
2576 tree id_list;
2577 tree id;
2578 tree nmi, warm;
2579 unsigned int lower_bound;
2580 unsigned int upper_bound;
2582 /* Prepare id_list and identify id value so that
2583 we can check if total number of vectors is valid. */
2584 id_list = TREE_VALUE (reset);
2585 id = TREE_VALUE (id_list);
2587 /* The maximum numbers for user's interrupt is 64. */
2588 lower_bound = 0;
2589 upper_bound = 64;
2591 /* 3. Check valid integer value for reset. */
2592 if (TREE_CODE (id) != INTEGER_CST
2593 || wi::ltu_p (id, lower_bound)
2594 || wi::gtu_p (id, upper_bound))
2595 error ("invalid id value for reset attribute");
2597 /* 4. Check valid function for nmi/warm. */
2598 nmi = lookup_attribute ("nmi", func_attrs);
2599 warm = lookup_attribute ("warm", func_attrs);
2601 if (nmi != NULL_TREE)
2603 tree nmi_func_list;
2604 tree nmi_func;
2606 nmi_func_list = TREE_VALUE (nmi);
2607 nmi_func = TREE_VALUE (nmi_func_list);
2609 /* Issue error if it is not a valid nmi function. */
2610 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2611 error ("invalid nmi function for reset attribute");
2614 if (warm != NULL_TREE)
2616 tree warm_func_list;
2617 tree warm_func;
2619 warm_func_list = TREE_VALUE (warm);
2620 warm_func = TREE_VALUE (warm_func_list);
2622 /* Issue error if it is not a valid warm function. */
2623 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2624 error ("invalid warm function for reset attribute");
2627 else
2629 /* No interrupt, exception, or reset attribute is set. */
2630 return;
2635 static bool
2636 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2637 tree pop_target ATTRIBUTE_UNUSED)
2639 /* Currently, we do not parse any pragma target by ourself,
2640 so just simply return false. */
2641 return false;
2644 static void
2645 nds32_option_override (void)
2647 /* After all the command options have been parsed,
2648 we shall deal with some flags for changing compiler settings. */
2650 /* At first, we check if we have to strictly
2651 set some flags based on ISA family. */
2652 if (TARGET_ISA_V2)
2654 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2655 target_flags &= ~MASK_V3PUSH;
2657 if (TARGET_ISA_V3)
2659 /* Under V3 ISA, currently nothing should be strictly set. */
2661 if (TARGET_ISA_V3M)
2663 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2664 target_flags |= MASK_REDUCED_REGS;
2665 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2666 target_flags &= ~MASK_PERF_EXT;
2669 /* See if we are using reduced-set registers:
2670 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2671 If so, we must forbid using $r11~$r14, $r16~$r27. */
2672 if (TARGET_REDUCED_REGS)
2674 int r;
2676 /* Prevent register allocator from
2677 choosing it as doing register allocation. */
2678 for (r = 11; r <= 14; r++)
2679 fixed_regs[r] = call_used_regs[r] = 1;
2680 for (r = 16; r <= 27; r++)
2681 fixed_regs[r] = call_used_regs[r] = 1;
2684 /* See if user explicitly would like to use fp-as-gp optimization.
2685 If so, we must prevent $fp from being allocated
2686 during register allocation. */
2687 if (TARGET_FORCE_FP_AS_GP)
2688 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2690 if (!TARGET_16_BIT)
2692 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2693 target_flags &= ~MASK_V3PUSH;
2696 /* Currently, we don't support PIC code generation yet. */
2697 if (flag_pic)
2698 sorry ("not support -fpic");
2702 /* Miscellaneous Parameters. */
2704 static void
2705 nds32_init_builtins (void)
2707 nds32_init_builtins_impl ();
2710 static rtx
2711 nds32_expand_builtin (tree exp,
2712 rtx target,
2713 rtx subtarget,
2714 machine_mode mode,
2715 int ignore)
2717 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2721 /* ------------------------------------------------------------------------ */
2723 /* PART 4: Implemet extern function definitions,
2724 the prototype is in nds32-protos.h. */
2726 /* Defining Data Structures for Per-function Information. */
2728 void
2729 nds32_init_expanders (void)
2731 /* Arrange to initialize and mark the machine per-function status. */
2732 init_machine_status = nds32_init_machine_status;
2736 /* Register Usage. */
2738 /* -- How Values Fit in Registers. */
2741 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2742 machine_mode mode)
2744 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2748 nds32_hard_regno_mode_ok (int regno, machine_mode mode)
2750 /* Restrict double-word quantities to even register pairs. */
2751 if (HARD_REGNO_NREGS (regno, mode) == 1
2752 || !((regno) & 1))
2753 return 1;
2755 return 0;
2759 /* Register Classes. */
2761 enum reg_class
2762 nds32_regno_reg_class (int regno)
2764 /* Refer to nds32.h for more register class details. */
2766 if (regno >= 0 && regno <= 7)
2767 return LOW_REGS;
2768 else if (regno >= 8 && regno <= 11)
2769 return MIDDLE_REGS;
2770 else if (regno >= 12 && regno <= 14)
2771 return HIGH_REGS;
2772 else if (regno == 15)
2773 return R15_TA_REG;
2774 else if (regno >= 16 && regno <= 19)
2775 return MIDDLE_REGS;
2776 else if (regno >= 20 && regno <= 31)
2777 return HIGH_REGS;
2778 else if (regno == 32 || regno == 33)
2779 return FRAME_REGS;
2780 else
2781 return NO_REGS;
2785 /* Stack Layout and Calling Conventions. */
2787 /* -- Basic Stack Layout. */
2790 nds32_return_addr_rtx (int count,
2791 rtx frameaddr ATTRIBUTE_UNUSED)
2793 /* There is no way to determine the return address
2794 if frameaddr is the frame that has 'count' steps
2795 up from current frame. */
2796 if (count != 0)
2797 return NULL_RTX;
2799 /* If count == 0, it means we are at current frame,
2800 the return address is $r30 ($lp). */
2801 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2804 /* -- Eliminating Frame Pointer and Arg Pointer. */
2806 HOST_WIDE_INT
2807 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2809 HOST_WIDE_INT offset;
2811 /* Compute and setup stack frame size.
2812 The result will be in cfun->machine. */
2813 nds32_compute_stack_frame ();
2815 /* Remember to consider
2816 cfun->machine->callee_saved_area_padding_bytes
2817 when calculating offset. */
2818 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2820 offset = (cfun->machine->fp_size
2821 + cfun->machine->gp_size
2822 + cfun->machine->lp_size
2823 + cfun->machine->callee_saved_regs_size
2824 + cfun->machine->callee_saved_area_padding_bytes
2825 + cfun->machine->local_size
2826 + cfun->machine->out_args_size);
2828 else if (from_reg == ARG_POINTER_REGNUM
2829 && to_reg == HARD_FRAME_POINTER_REGNUM)
2831 offset = 0;
2833 else if (from_reg == FRAME_POINTER_REGNUM
2834 && to_reg == STACK_POINTER_REGNUM)
2836 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2838 else if (from_reg == FRAME_POINTER_REGNUM
2839 && to_reg == HARD_FRAME_POINTER_REGNUM)
2841 offset = (-1) * (cfun->machine->fp_size
2842 + cfun->machine->gp_size
2843 + cfun->machine->lp_size
2844 + cfun->machine->callee_saved_regs_size
2845 + cfun->machine->callee_saved_area_padding_bytes);
2847 else
2849 gcc_unreachable ();
2852 return offset;
2855 /* -- Passing Arguments in Registers. */
2857 void
2858 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2859 tree fntype ATTRIBUTE_UNUSED,
2860 rtx libname ATTRIBUTE_UNUSED,
2861 tree fndecl ATTRIBUTE_UNUSED,
2862 int n_named_args ATTRIBUTE_UNUSED)
2864 /* Initial available registers
2865 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2866 for passing arguments. */
2867 cum->gpr_offset = 0;
2870 /* -- Function Entry and Exit. */
2872 /* Function for normal multiple push prologue. */
2873 void
2874 nds32_expand_prologue (void)
2876 int fp_adjust;
2877 int sp_adjust;
2878 int en4_const;
2880 rtx Rb, Re;
2881 rtx fp_adjust_insn, sp_adjust_insn;
2883 /* Compute and setup stack frame size.
2884 The result will be in cfun->machine. */
2885 nds32_compute_stack_frame ();
2887 /* If this is a variadic function, first we need to push argument
2888 registers that hold the unnamed argument value. */
2889 if (cfun->machine->va_args_size != 0)
2891 Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
2892 Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
2893 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2894 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0), true);
2896 /* We may also need to adjust stack pointer for padding bytes
2897 because varargs may cause $sp not 8-byte aligned. */
2898 if (cfun->machine->va_args_area_padding_bytes)
2900 /* Generate sp adjustment instruction. */
2901 sp_adjust = cfun->machine->va_args_area_padding_bytes;
2902 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2903 stack_pointer_rtx,
2904 GEN_INT (-1 * sp_adjust));
2906 /* Emit rtx into instructions list and receive INSN rtx form. */
2907 sp_adjust_insn = emit_insn (sp_adjust_insn);
2909 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2910 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2911 generate CFI (Call Frame Information) stuff. */
2912 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2916 /* If the function is 'naked',
2917 we do not have to generate prologue code fragment. */
2918 if (cfun->machine->naked_p)
2919 return;
2921 /* Get callee_first_regno and callee_last_regno. */
2922 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2923 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2925 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2926 the pattern 'stack_push_multiple' is implemented in nds32.md.
2927 For En4 field, we have to calculate its constant value.
2928 Refer to Andes ISA for more information. */
2929 en4_const = 0;
2930 if (cfun->machine->fp_size)
2931 en4_const += 8;
2932 if (cfun->machine->gp_size)
2933 en4_const += 4;
2934 if (cfun->machine->lp_size)
2935 en4_const += 2;
2937 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2938 to be saved, we don't have to create multiple push instruction.
2939 Otherwise, a multiple push instruction is needed. */
2940 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2942 /* Create multiple push instruction rtx. */
2943 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const), false);
2946 /* Check frame_pointer_needed to see
2947 if we shall emit fp adjustment instruction. */
2948 if (frame_pointer_needed)
2950 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2951 + (4 * callee-saved-registers)
2952 Note: No need to adjust
2953 cfun->machine->callee_saved_area_padding_bytes,
2954 because, at this point, stack pointer is just
2955 at the position after push instruction. */
2956 fp_adjust = cfun->machine->fp_size
2957 + cfun->machine->gp_size
2958 + cfun->machine->lp_size
2959 + cfun->machine->callee_saved_regs_size;
2960 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2961 stack_pointer_rtx,
2962 GEN_INT (fp_adjust));
2963 /* Emit rtx into instructions list and receive INSN rtx form. */
2964 fp_adjust_insn = emit_insn (fp_adjust_insn);
2966 /* The insn rtx 'fp_adjust_insn' will change frame layout. */
2967 RTX_FRAME_RELATED_P (fp_adjust_insn) = 1;
2970 /* Adjust $sp = $sp - local_size - out_args_size
2971 - callee_saved_area_padding_bytes. */
2972 sp_adjust = cfun->machine->local_size
2973 + cfun->machine->out_args_size
2974 + cfun->machine->callee_saved_area_padding_bytes;
2975 /* sp_adjust value may be out of range of the addi instruction,
2976 create alternative add behavior with TA_REGNUM if necessary,
2977 using NEGATIVE value to tell that we are decreasing address. */
2978 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2979 if (sp_adjust)
2981 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2982 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2983 stack_pointer_rtx,
2984 GEN_INT (-1 * sp_adjust));
2985 /* Emit rtx into instructions list and receive INSN rtx form. */
2986 sp_adjust_insn = emit_insn (sp_adjust_insn);
2988 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2989 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2990 generate CFI (Call Frame Information) stuff. */
2991 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2994 /* Prevent the instruction scheduler from
2995 moving instructions across the boundary. */
2996 emit_insn (gen_blockage ());
2999 /* Function for normal multiple pop epilogue. */
3000 void
3001 nds32_expand_epilogue (void)
3003 int sp_adjust;
3004 int en4_const;
3006 rtx Rb, Re;
3007 rtx sp_adjust_insn;
3009 /* Compute and setup stack frame size.
3010 The result will be in cfun->machine. */
3011 nds32_compute_stack_frame ();
3013 /* Prevent the instruction scheduler from
3014 moving instructions across the boundary. */
3015 emit_insn (gen_blockage ());
3017 /* If the function is 'naked', we do not have to generate
3018 epilogue code fragment BUT 'ret' instruction.
3019 However, if this function is also a variadic function,
3020 we need to create adjust stack pointer before 'ret' instruction. */
3021 if (cfun->machine->naked_p)
3023 /* If this is a variadic function, we do not have to restore argument
3024 registers but need to adjust stack pointer back to previous stack
3025 frame location before return. */
3026 if (cfun->machine->va_args_size != 0)
3028 /* Generate sp adjustment instruction.
3029 We need to consider padding bytes here. */
3030 sp_adjust = cfun->machine->va_args_size
3031 + cfun->machine->va_args_area_padding_bytes;
3032 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3033 stack_pointer_rtx,
3034 GEN_INT (sp_adjust));
3035 /* Emit rtx into instructions list and receive INSN rtx form. */
3036 sp_adjust_insn = emit_insn (sp_adjust_insn);
3038 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3039 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3040 generate CFI (Call Frame Information) stuff. */
3041 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3044 /* Generate return instruction by using
3045 unspec_volatile_func_return pattern.
3046 Make sure this instruction is after gen_blockage().
3047 NOTE that $lp will become 'live'
3048 after this instruction has been emitted. */
3049 emit_insn (gen_unspec_volatile_func_return ());
3050 return;
3053 if (frame_pointer_needed)
3055 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3056 - (4 * callee-saved-registers)
3057 Note: No need to adjust
3058 cfun->machine->callee_saved_area_padding_bytes,
3059 because we want to adjust stack pointer
3060 to the position for pop instruction. */
3061 sp_adjust = cfun->machine->fp_size
3062 + cfun->machine->gp_size
3063 + cfun->machine->lp_size
3064 + cfun->machine->callee_saved_regs_size;
3065 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3066 hard_frame_pointer_rtx,
3067 GEN_INT (-1 * sp_adjust));
3068 /* Emit rtx into instructions list and receive INSN rtx form. */
3069 sp_adjust_insn = emit_insn (sp_adjust_insn);
3071 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3072 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3074 else
3076 /* If frame pointer is NOT needed,
3077 we cannot calculate the sp adjustment from frame pointer.
3078 Instead, we calculate the adjustment by local_size,
3079 out_args_size, and callee_saved_area_padding_bytes.
3080 Notice that such sp adjustment value may be out of range,
3081 so we have to deal with it as well. */
3083 /* Adjust $sp = $sp + local_size + out_args_size
3084 + callee_saved_area_padding_bytes. */
3085 sp_adjust = cfun->machine->local_size
3086 + cfun->machine->out_args_size
3087 + cfun->machine->callee_saved_area_padding_bytes;
3088 /* sp_adjust value may be out of range of the addi instruction,
3089 create alternative add behavior with TA_REGNUM if necessary,
3090 using POSITIVE value to tell that we are increasing address. */
3091 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3092 if (sp_adjust)
3094 /* Generate sp adjustment instruction
3095 if and only if sp_adjust != 0. */
3096 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3097 stack_pointer_rtx,
3098 GEN_INT (sp_adjust));
3099 /* Emit rtx into instructions list and receive INSN rtx form. */
3100 sp_adjust_insn = emit_insn (sp_adjust_insn);
3102 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3103 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3107 /* Get callee_first_regno and callee_last_regno. */
3108 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3109 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3111 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3112 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3113 For En4 field, we have to calculate its constant value.
3114 Refer to Andes ISA for more information. */
3115 en4_const = 0;
3116 if (cfun->machine->fp_size)
3117 en4_const += 8;
3118 if (cfun->machine->gp_size)
3119 en4_const += 4;
3120 if (cfun->machine->lp_size)
3121 en4_const += 2;
3123 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3124 to be saved, we don't have to create multiple pop instruction.
3125 Otherwise, a multiple pop instruction is needed. */
3126 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3128 /* Create multiple pop instruction rtx. */
3129 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3132 /* If this is a variadic function, we do not have to restore argument
3133 registers but need to adjust stack pointer back to previous stack
3134 frame location before return. */
3135 if (cfun->machine->va_args_size != 0)
3137 /* Generate sp adjustment instruction.
3138 We need to consider padding bytes here. */
3139 sp_adjust = cfun->machine->va_args_size
3140 + cfun->machine->va_args_area_padding_bytes;
3141 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3142 stack_pointer_rtx,
3143 GEN_INT (sp_adjust));
3144 /* Emit rtx into instructions list and receive INSN rtx form. */
3145 sp_adjust_insn = emit_insn (sp_adjust_insn);
3147 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3148 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3149 generate CFI (Call Frame Information) stuff. */
3150 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3153 /* Generate return instruction by using
3154 unspec_volatile_func_return pattern. */
3155 emit_insn (gen_unspec_volatile_func_return ());
3158 /* Function for v3push prologue. */
3159 void
3160 nds32_expand_prologue_v3push (void)
3162 int fp_adjust;
3163 int sp_adjust;
3165 rtx Rb, Re;
3166 rtx fp_adjust_insn, sp_adjust_insn;
3168 /* Compute and setup stack frame size.
3169 The result will be in cfun->machine. */
3170 nds32_compute_stack_frame ();
3172 /* If the function is 'naked',
3173 we do not have to generate prologue code fragment. */
3174 if (cfun->machine->naked_p)
3175 return;
3177 /* Get callee_first_regno and callee_last_regno. */
3178 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3179 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3181 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3182 where imm8u has to be 8-byte alignment. */
3183 sp_adjust = cfun->machine->local_size
3184 + cfun->machine->out_args_size
3185 + cfun->machine->callee_saved_area_padding_bytes;
3187 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3188 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3190 /* We can use 'push25 Re,imm8u'. */
3192 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3193 the pattern 'stack_v3push' is implemented in nds32.md.
3194 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3195 nds32_emit_stack_v3push (Rb, Re,
3196 GEN_INT (14), GEN_INT (sp_adjust));
3198 /* Check frame_pointer_needed to see
3199 if we shall emit fp adjustment instruction. */
3200 if (frame_pointer_needed)
3202 /* adjust $fp = $sp + 4 ($fp size)
3203 + 4 ($gp size)
3204 + 4 ($lp size)
3205 + (4 * n) (callee-saved registers)
3206 + sp_adjust ('push25 Re,imm8u')
3207 Note: Since we use 'push25 Re,imm8u',
3208 the position of stack pointer is further
3209 changed after push instruction.
3210 Hence, we need to take sp_adjust value
3211 into consideration. */
3212 fp_adjust = cfun->machine->fp_size
3213 + cfun->machine->gp_size
3214 + cfun->machine->lp_size
3215 + cfun->machine->callee_saved_regs_size
3216 + sp_adjust;
3217 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3218 stack_pointer_rtx,
3219 GEN_INT (fp_adjust));
3220 /* Emit rtx into instructions list and receive INSN rtx form. */
3221 fp_adjust_insn = emit_insn (fp_adjust_insn);
3224 else
3226 /* We have to use 'push25 Re,0' and
3227 expand one more instruction to adjust $sp later. */
3229 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3230 the pattern 'stack_v3push' is implemented in nds32.md.
3231 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3232 nds32_emit_stack_v3push (Rb, Re,
3233 GEN_INT (14), GEN_INT (0));
3235 /* Check frame_pointer_needed to see
3236 if we shall emit fp adjustment instruction. */
3237 if (frame_pointer_needed)
3239 /* adjust $fp = $sp + 4 ($fp size)
3240 + 4 ($gp size)
3241 + 4 ($lp size)
3242 + (4 * n) (callee-saved registers)
3243 Note: Since we use 'push25 Re,0',
3244 the stack pointer is just at the position
3245 after push instruction.
3246 No need to take sp_adjust into consideration. */
3247 fp_adjust = cfun->machine->fp_size
3248 + cfun->machine->gp_size
3249 + cfun->machine->lp_size
3250 + cfun->machine->callee_saved_regs_size;
3251 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3252 stack_pointer_rtx,
3253 GEN_INT (fp_adjust));
3254 /* Emit rtx into instructions list and receive INSN rtx form. */
3255 fp_adjust_insn = emit_insn (fp_adjust_insn);
3258 /* Because we use 'push25 Re,0',
3259 we need to expand one more instruction to adjust $sp.
3260 However, sp_adjust value may be out of range of the addi instruction,
3261 create alternative add behavior with TA_REGNUM if necessary,
3262 using NEGATIVE value to tell that we are decreasing address. */
3263 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3264 if (sp_adjust)
3266 /* Generate sp adjustment instruction
3267 if and only if sp_adjust != 0. */
3268 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3269 stack_pointer_rtx,
3270 GEN_INT (-1 * sp_adjust));
3271 /* Emit rtx into instructions list and receive INSN rtx form. */
3272 sp_adjust_insn = emit_insn (sp_adjust_insn);
3274 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3275 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3276 generate CFI (Call Frame Information) stuff. */
3277 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3281 /* Prevent the instruction scheduler from
3282 moving instructions across the boundary. */
3283 emit_insn (gen_blockage ());
3286 /* Function for v3pop epilogue. */
3287 void
3288 nds32_expand_epilogue_v3pop (void)
3290 int sp_adjust;
3292 rtx Rb, Re;
3293 rtx sp_adjust_insn;
3295 /* Compute and setup stack frame size.
3296 The result will be in cfun->machine. */
3297 nds32_compute_stack_frame ();
3299 /* Prevent the instruction scheduler from
3300 moving instructions across the boundary. */
3301 emit_insn (gen_blockage ());
3303 /* If the function is 'naked', we do not have to generate
3304 epilogue code fragment BUT 'ret' instruction. */
3305 if (cfun->machine->naked_p)
3307 /* Generate return instruction by using
3308 unspec_volatile_func_return pattern.
3309 Make sure this instruction is after gen_blockage().
3310 NOTE that $lp will become 'live'
3311 after this instruction has been emitted. */
3312 emit_insn (gen_unspec_volatile_func_return ());
3313 return;
3316 /* Get callee_first_regno and callee_last_regno. */
3317 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3318 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3320 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3321 where imm8u has to be 8-byte alignment. */
3322 sp_adjust = cfun->machine->local_size
3323 + cfun->machine->out_args_size
3324 + cfun->machine->callee_saved_area_padding_bytes;
3326 /* We have to consider alloca issue as well.
3327 If the function does call alloca(), the stack pointer is not fixed.
3328 In that case, we cannot use 'pop25 Re,imm8u' directly.
3329 We have to caculate stack pointer from frame pointer
3330 and then use 'pop25 Re,0'.
3331 Of course, the frame_pointer_needed should be nonzero
3332 if the function calls alloca(). */
3333 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3334 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3335 && !cfun->calls_alloca)
3337 /* We can use 'pop25 Re,imm8u'. */
3339 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3340 the pattern 'stack_v3pop' is implementad in nds32.md.
3341 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3342 nds32_emit_stack_v3pop (Rb, Re,
3343 GEN_INT (14), GEN_INT (sp_adjust));
3345 else
3347 /* We have to use 'pop25 Re,0', and prior to it,
3348 we must expand one more instruction to adjust $sp. */
3350 if (frame_pointer_needed)
3352 /* adjust $sp = $fp - 4 ($fp size)
3353 - 4 ($gp size)
3354 - 4 ($lp size)
3355 - (4 * n) (callee-saved registers)
3356 Note: No need to adjust
3357 cfun->machine->callee_saved_area_padding_bytes,
3358 because we want to adjust stack pointer
3359 to the position for pop instruction. */
3360 sp_adjust = cfun->machine->fp_size
3361 + cfun->machine->gp_size
3362 + cfun->machine->lp_size
3363 + cfun->machine->callee_saved_regs_size;
3364 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3365 hard_frame_pointer_rtx,
3366 GEN_INT (-1 * sp_adjust));
3367 /* Emit rtx into instructions list and receive INSN rtx form. */
3368 sp_adjust_insn = emit_insn (sp_adjust_insn);
3370 else
3372 /* If frame pointer is NOT needed,
3373 we cannot calculate the sp adjustment from frame pointer.
3374 Instead, we calculate the adjustment by local_size,
3375 out_args_size, and callee_saved_area_padding_bytes.
3376 Notice that such sp adjustment value may be out of range,
3377 so we have to deal with it as well. */
3379 /* Adjust $sp = $sp + local_size + out_args_size
3380 + callee_saved_area_padding_bytes. */
3381 sp_adjust = cfun->machine->local_size
3382 + cfun->machine->out_args_size
3383 + cfun->machine->callee_saved_area_padding_bytes;
3384 /* sp_adjust value may be out of range of the addi instruction,
3385 create alternative add behavior with TA_REGNUM if necessary,
3386 using POSITIVE value to tell that we are increasing address. */
3387 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3388 if (sp_adjust)
3390 /* Generate sp adjustment instruction
3391 if and only if sp_adjust != 0. */
3392 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3393 stack_pointer_rtx,
3394 GEN_INT (sp_adjust));
3395 /* Emit rtx into instructions list and receive INSN rtx form. */
3396 sp_adjust_insn = emit_insn (sp_adjust_insn);
3400 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3401 the pattern 'stack_v3pop' is implementad in nds32.md. */
3402 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3403 nds32_emit_stack_v3pop (Rb, Re,
3404 GEN_INT (14), GEN_INT (0));
3408 /* ------------------------------------------------------------------------ */
3410 /* Function to test 333-form for load/store instructions.
3411 This is auxiliary extern function for auxiliary macro in nds32.h.
3412 Because it is a little complicated, we use function instead of macro. */
3413 bool
3414 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
3416 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3417 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3419 if (GET_MODE_SIZE (mode) == 4)
3420 return satisfies_constraint_Iu05 (imm);
3422 if (GET_MODE_SIZE (mode) == 2)
3423 return satisfies_constraint_Iu04 (imm);
3425 if (GET_MODE_SIZE (mode) == 1)
3426 return satisfies_constraint_Iu03 (imm);
3429 return false;
3433 /* Computing the Length of an Insn.
3434 Modifies the length assigned to instruction INSN.
3435 LEN is the initially computed length of the insn. */
3437 nds32_adjust_insn_length (rtx_insn *insn, int length)
3439 rtx src, dst;
3441 switch (recog_memoized (insn))
3443 case CODE_FOR_move_df:
3444 case CODE_FOR_move_di:
3445 /* Adjust length of movd44 to 2. */
3446 src = XEXP (PATTERN (insn), 1);
3447 dst = XEXP (PATTERN (insn), 0);
3449 if (REG_P (src)
3450 && REG_P (dst)
3451 && (REGNO (src) % 2) == 0
3452 && (REGNO (dst) % 2) == 0)
3453 length = 2;
3454 break;
3456 default:
3457 break;
3460 return length;
3464 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3466 nds32_target_alignment (rtx label)
3468 rtx_insn *insn;
3470 if (optimize_size)
3471 return 0;
3473 insn = next_active_insn (label);
3475 if (insn == 0)
3476 return 0;
3477 else if ((get_attr_length (insn) % 4) == 0)
3478 return 2;
3479 else
3480 return 0;
3483 /* ------------------------------------------------------------------------ */
3485 /* PART 5: Initialize target hook structure and definitions. */
3487 /* Controlling the Compilation Driver. */
3490 /* Run-time Target Specification. */
3493 /* Defining Data Structures for Per-function Information. */
3496 /* Storage Layout. */
3498 #undef TARGET_PROMOTE_FUNCTION_MODE
3499 #define TARGET_PROMOTE_FUNCTION_MODE \
3500 default_promote_function_mode_always_promote
3503 /* Layout of Source Language Data Types. */
3506 /* Register Usage. */
3508 /* -- Basic Characteristics of Registers. */
3510 /* -- Order of Allocation of Registers. */
3512 /* -- How Values Fit in Registers. */
3514 /* -- Handling Leaf Functions. */
3516 /* -- Registers That Form a Stack. */
3519 /* Register Classes. */
3521 #undef TARGET_CLASS_MAX_NREGS
3522 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3524 #undef TARGET_LRA_P
3525 #define TARGET_LRA_P hook_bool_void_true
3527 #undef TARGET_REGISTER_PRIORITY
3528 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3531 /* Obsolete Macros for Defining Constraints. */
3534 /* Stack Layout and Calling Conventions. */
3536 /* -- Basic Stack Layout. */
3538 /* -- Exception Handling Support. */
3540 /* -- Specifying How Stack Checking is Done. */
3542 /* -- Registers That Address the Stack Frame. */
3544 /* -- Eliminating Frame Pointer and Arg Pointer. */
3546 #undef TARGET_CAN_ELIMINATE
3547 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3549 /* -- Passing Function Arguments on the Stack. */
3551 /* -- Passing Arguments in Registers. */
3553 #undef TARGET_FUNCTION_ARG
3554 #define TARGET_FUNCTION_ARG nds32_function_arg
3556 #undef TARGET_MUST_PASS_IN_STACK
3557 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3559 #undef TARGET_ARG_PARTIAL_BYTES
3560 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3562 #undef TARGET_FUNCTION_ARG_ADVANCE
3563 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3565 #undef TARGET_FUNCTION_ARG_BOUNDARY
3566 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3568 /* -- How Scalar Function Values Are Returned. */
3570 #undef TARGET_FUNCTION_VALUE
3571 #define TARGET_FUNCTION_VALUE nds32_function_value
3573 #undef TARGET_LIBCALL_VALUE
3574 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3576 #undef TARGET_FUNCTION_VALUE_REGNO_P
3577 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3579 /* -- How Large Values Are Returned. */
3581 /* -- Caller-Saves Register Allocation. */
3583 /* -- Function Entry and Exit. */
3585 #undef TARGET_ASM_FUNCTION_PROLOGUE
3586 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3588 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3589 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3591 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3592 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3594 #undef TARGET_ASM_FUNCTION_EPILOGUE
3595 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3597 #undef TARGET_ASM_OUTPUT_MI_THUNK
3598 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3600 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3601 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3603 /* -- Generating Code for Profiling. */
3605 /* -- Permitting tail calls. */
3607 #undef TARGET_WARN_FUNC_RETURN
3608 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3610 /* Stack smashing protection. */
3613 /* Implementing the Varargs Macros. */
3615 #undef TARGET_SETUP_INCOMING_VARARGS
3616 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3618 #undef TARGET_STRICT_ARGUMENT_NAMING
3619 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3622 /* Trampolines for Nested Functions. */
3624 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3625 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3627 #undef TARGET_TRAMPOLINE_INIT
3628 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3631 /* Implicit Calls to Library Routines. */
3634 /* Addressing Modes. */
3636 #undef TARGET_LEGITIMATE_ADDRESS_P
3637 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3640 /* Anchored Addresses. */
3643 /* Condition Code Status. */
3645 /* -- Representation of condition codes using (cc0). */
3647 /* -- Representation of condition codes using registers. */
3649 /* -- Macros to control conditional execution. */
3652 /* Describing Relative Costs of Operations. */
3654 #undef TARGET_REGISTER_MOVE_COST
3655 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3657 #undef TARGET_MEMORY_MOVE_COST
3658 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3660 #undef TARGET_RTX_COSTS
3661 #define TARGET_RTX_COSTS nds32_rtx_costs
3663 #undef TARGET_ADDRESS_COST
3664 #define TARGET_ADDRESS_COST nds32_address_cost
3667 /* Adjusting the Instruction Scheduler. */
3670 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3673 /* Position Independent Code. */
3676 /* Defining the Output Assembler Language. */
3678 /* -- The Overall Framework of an Assembler File. */
3680 #undef TARGET_ASM_FILE_START
3681 #define TARGET_ASM_FILE_START nds32_asm_file_start
3682 #undef TARGET_ASM_FILE_END
3683 #define TARGET_ASM_FILE_END nds32_asm_file_end
3685 /* -- Output of Data. */
3687 #undef TARGET_ASM_ALIGNED_HI_OP
3688 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3690 #undef TARGET_ASM_ALIGNED_SI_OP
3691 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3693 /* -- Output of Uninitialized Variables. */
3695 /* -- Output and Generation of Labels. */
3697 #undef TARGET_ASM_GLOBALIZE_LABEL
3698 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3700 /* -- How Initialization Functions Are Handled. */
3702 /* -- Macros Controlling Initialization Routines. */
3704 /* -- Output of Assembler Instructions. */
3706 #undef TARGET_PRINT_OPERAND
3707 #define TARGET_PRINT_OPERAND nds32_print_operand
3708 #undef TARGET_PRINT_OPERAND_ADDRESS
3709 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3711 /* -- Output of Dispatch Tables. */
3713 /* -- Assembler Commands for Exception Regions. */
3715 /* -- Assembler Commands for Alignment. */
3718 /* Controlling Debugging Information Format. */
3720 /* -- Macros Affecting All Debugging Formats. */
3722 /* -- Specific Options for DBX Output. */
3724 /* -- Open-Ended Hooks for DBX Format. */
3726 /* -- File Names in DBX Format. */
3728 /* -- Macros for SDB and DWARF Output. */
3730 /* -- Macros for VMS Debug Format. */
3733 /* Cross Compilation and Floating Point. */
3736 /* Mode Switching Instructions. */
3739 /* Defining target-specific uses of __attribute__. */
3741 #undef TARGET_ATTRIBUTE_TABLE
3742 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3744 #undef TARGET_MERGE_DECL_ATTRIBUTES
3745 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3747 #undef TARGET_INSERT_ATTRIBUTES
3748 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3750 #undef TARGET_OPTION_PRAGMA_PARSE
3751 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3753 #undef TARGET_OPTION_OVERRIDE
3754 #define TARGET_OPTION_OVERRIDE nds32_option_override
3757 /* Emulating TLS. */
3760 /* Defining coprocessor specifics for MIPS targets. */
3763 /* Parameters for Precompiled Header Validity Checking. */
3766 /* C++ ABI parameters. */
3769 /* Adding support for named address spaces. */
3772 /* Miscellaneous Parameters. */
3774 #undef TARGET_INIT_BUILTINS
3775 #define TARGET_INIT_BUILTINS nds32_init_builtins
3777 #undef TARGET_EXPAND_BUILTIN
3778 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3781 /* ------------------------------------------------------------------------ */
3783 /* Initialize the GCC target structure. */
3785 struct gcc_target targetm = TARGET_INITIALIZER;
3787 /* ------------------------------------------------------------------------ */