PR target/84064
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob08331f324a45b8dd406018b9a2c9f99eef637bf1
1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 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 #define IN_TARGET_CODE 1
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "stringpool.h"
33 #include "attribs.h"
34 #include "df.h"
35 #include "memmodel.h"
36 #include "tm_p.h"
37 #include "optabs.h" /* For GEN_FCN. */
38 #include "regs.h"
39 #include "emit-rtl.h"
40 #include "recog.h"
41 #include "diagnostic-core.h"
42 #include "stor-layout.h"
43 #include "varasm.h"
44 #include "calls.h"
45 #include "output.h"
46 #include "explow.h"
47 #include "expr.h"
48 #include "tm-constrs.h"
49 #include "builtins.h"
51 /* This file should be included last. */
52 #include "target-def.h"
54 /* ------------------------------------------------------------------------ */
56 /* This file is divided into five parts:
58 PART 1: Auxiliary static variable definitions and
59 target hook static variable definitions.
61 PART 2: Auxiliary static function definitions.
63 PART 3: Implement target hook stuff definitions.
65 PART 4: Implemet extern function definitions,
66 the prototype is in nds32-protos.h.
68 PART 5: Initialize target hook structure and definitions. */
70 /* ------------------------------------------------------------------------ */
72 /* PART 1: Auxiliary static variable definitions and
73 target hook static variable definitions. */
75 /* Define intrinsic register names.
76 Please refer to nds32_intrinsic.h file, the index is corresponding to
77 'enum nds32_intrinsic_registers' data type values.
78 NOTE that the base value starting from 1024. */
79 static const char * const nds32_intrinsic_register_names[] =
81 "$PSW", "$IPSW", "$ITYPE", "$IPC"
84 /* Defining target-specific uses of __attribute__. */
85 static const struct attribute_spec nds32_attribute_table[] =
87 /* Syntax: { name, min_len, max_len, decl_required, type_required,
88 function_type_required, affects_type_identity, handler,
89 exclude } */
91 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
92 { "interrupt", 1, 64, false, false, false, false, NULL, NULL },
93 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
94 { "exception", 1, 8, false, false, false, false, NULL, NULL },
95 /* Argument is user's interrupt numbers. The vector number is always 0. */
96 { "reset", 1, 1, false, false, false, false, NULL, NULL },
98 /* The attributes describing isr nested type. */
99 { "nested", 0, 0, false, false, false, false, NULL, NULL },
100 { "not_nested", 0, 0, false, false, false, false, NULL, NULL },
101 { "nested_ready", 0, 0, false, false, false, false, NULL, NULL },
103 /* The attributes describing isr register save scheme. */
104 { "save_all", 0, 0, false, false, false, false, NULL, NULL },
105 { "partial_save", 0, 0, false, false, false, false, NULL, NULL },
107 /* The attributes used by reset attribute. */
108 { "nmi", 1, 1, false, false, false, false, NULL, NULL },
109 { "warm", 1, 1, false, false, false, false, NULL, NULL },
111 /* The attribute telling no prologue/epilogue. */
112 { "naked", 0, 0, false, false, false, false, NULL, NULL },
114 /* The last attribute spec is set to be NULL. */
115 { NULL, 0, 0, false, false, false, false, NULL, NULL }
119 /* ------------------------------------------------------------------------ */
121 /* PART 2: Auxiliary static function definitions. */
123 /* Function to save and restore machine-specific function data. */
124 static struct machine_function *
125 nds32_init_machine_status (void)
127 struct machine_function *machine;
128 machine = ggc_cleared_alloc<machine_function> ();
130 /* Initially assume this function needs prologue/epilogue. */
131 machine->naked_p = 0;
133 /* Initially assume this function does NOT use fp_as_gp optimization. */
134 machine->fp_as_gp_p = 0;
136 return machine;
139 /* Function to compute stack frame size and
140 store into cfun->machine structure. */
141 static void
142 nds32_compute_stack_frame (void)
144 int r;
145 int block_size;
147 /* Because nds32_compute_stack_frame() will be called from different place,
148 everytime we enter this function, we have to assume this function
149 needs prologue/epilogue. */
150 cfun->machine->naked_p = 0;
152 /* Get variadic arguments size to prepare pretend arguments and
153 we will push them into stack at prologue by ourself. */
154 cfun->machine->va_args_size = crtl->args.pretend_args_size;
155 if (cfun->machine->va_args_size != 0)
157 cfun->machine->va_args_first_regno
158 = NDS32_GPR_ARG_FIRST_REGNUM
159 + NDS32_MAX_GPR_REGS_FOR_ARGS
160 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
161 cfun->machine->va_args_last_regno
162 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
164 else
166 cfun->machine->va_args_first_regno = SP_REGNUM;
167 cfun->machine->va_args_last_regno = SP_REGNUM;
170 /* Important: We need to make sure that varargs area is 8-byte alignment. */
171 block_size = cfun->machine->va_args_size;
172 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
174 cfun->machine->va_args_area_padding_bytes
175 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
178 /* Get local variables, incoming variables, and temporary variables size.
179 Note that we need to make sure it is 8-byte alignment because
180 there may be no padding bytes if we are using LRA. */
181 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
183 /* Get outgoing arguments size. */
184 cfun->machine->out_args_size = crtl->outgoing_args_size;
186 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
187 Check whether $fp is ever live. */
188 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
190 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
191 Check whether we are using PIC code genration. */
192 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
194 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
195 Check whether $lp is ever live. */
196 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
198 /* Initially there is no padding bytes. */
199 cfun->machine->callee_saved_area_gpr_padding_bytes = 0;
201 /* Calculate the bytes of saving callee-saved registers on stack. */
202 cfun->machine->callee_saved_gpr_regs_size = 0;
203 cfun->machine->callee_saved_first_gpr_regno = SP_REGNUM;
204 cfun->machine->callee_saved_last_gpr_regno = SP_REGNUM;
205 /* Currently, there is no need to check $r28~$r31
206 because we will save them in another way. */
207 for (r = 0; r < 28; r++)
209 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
211 /* Mark the first required callee-saved register
212 (only need to set it once).
213 If first regno == SP_REGNUM, we can tell that
214 it is the first time to be here. */
215 if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM)
216 cfun->machine->callee_saved_first_gpr_regno = r;
217 /* Mark the last required callee-saved register. */
218 cfun->machine->callee_saved_last_gpr_regno = r;
222 /* Check if this function can omit prologue/epilogue code fragment.
223 If there is 'naked' attribute in this function,
224 we can set 'naked_p' flag to indicate that
225 we do not have to generate prologue/epilogue.
226 Or, if all the following conditions succeed,
227 we can set this function 'naked_p' as well:
228 condition 1: first_regno == last_regno == SP_REGNUM,
229 which means we do not have to save
230 any callee-saved registers.
231 condition 2: Both $lp and $fp are NOT live in this function,
232 which means we do not need to save them and there
233 is no outgoing size.
234 condition 3: There is no local_size, which means
235 we do not need to adjust $sp. */
236 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
237 || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM
238 && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM
239 && !df_regs_ever_live_p (FP_REGNUM)
240 && !df_regs_ever_live_p (LP_REGNUM)
241 && cfun->machine->local_size == 0))
243 /* Set this function 'naked_p' and other functions can check this flag.
244 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
245 callee-saved, local size, and outgoing size.
246 The varargs space and ret instruction may still present in
247 the prologue/epilogue expanding. */
248 cfun->machine->naked_p = 1;
250 /* No need to save $fp, $gp, and $lp.
251 We should set these value to be zero
252 so that nds32_initial_elimination_offset() can work properly. */
253 cfun->machine->fp_size = 0;
254 cfun->machine->gp_size = 0;
255 cfun->machine->lp_size = 0;
257 /* If stack usage computation is required,
258 we need to provide the static stack size. */
259 if (flag_stack_usage_info)
260 current_function_static_stack_size = 0;
262 /* No need to do following adjustment, return immediately. */
263 return;
266 /* Adjustment for v3push instructions:
267 If we are using v3push (push25/pop25) instructions,
268 we need to make sure Rb is $r6 and Re is
269 located on $r6, $r8, $r10, or $r14.
270 Some results above will be discarded and recomputed.
271 Note that it is only available under V3/V3M ISA and we
272 DO NOT setup following stuff for isr or variadic function. */
273 if (TARGET_V3PUSH
274 && !nds32_isr_function_p (current_function_decl)
275 && (cfun->machine->va_args_size == 0))
277 /* Recompute:
278 cfun->machine->fp_size
279 cfun->machine->gp_size
280 cfun->machine->lp_size
281 cfun->machine->callee_saved_first_gpr_regno
282 cfun->machine->callee_saved_last_gpr_regno */
284 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
285 cfun->machine->fp_size = 4;
286 cfun->machine->gp_size = 4;
287 cfun->machine->lp_size = 4;
289 /* Remember to set Rb = $r6. */
290 cfun->machine->callee_saved_first_gpr_regno = 6;
292 if (cfun->machine->callee_saved_last_gpr_regno <= 6)
294 /* Re = $r6 */
295 cfun->machine->callee_saved_last_gpr_regno = 6;
297 else if (cfun->machine->callee_saved_last_gpr_regno <= 8)
299 /* Re = $r8 */
300 cfun->machine->callee_saved_last_gpr_regno = 8;
302 else if (cfun->machine->callee_saved_last_gpr_regno <= 10)
304 /* Re = $r10 */
305 cfun->machine->callee_saved_last_gpr_regno = 10;
307 else if (cfun->machine->callee_saved_last_gpr_regno <= 14)
309 /* Re = $r14 */
310 cfun->machine->callee_saved_last_gpr_regno = 14;
312 else if (cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM)
314 /* If last_regno is SP_REGNUM, which means
315 it is never changed, so set it to Re = $r6. */
316 cfun->machine->callee_saved_last_gpr_regno = 6;
318 else
320 /* The program flow should not go here. */
321 gcc_unreachable ();
325 /* We have correctly set callee_saved_first_gpr_regno
326 and callee_saved_last_gpr_regno.
327 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
328 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
329 we can update callee_saved_gpr_regs_size with new size. */
330 if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM)
332 /* Compute pushed size of callee-saved registers. */
333 cfun->machine->callee_saved_gpr_regs_size
334 = 4 * (cfun->machine->callee_saved_last_gpr_regno
335 - cfun->machine->callee_saved_first_gpr_regno
336 + 1);
339 /* Important: We need to make sure that
340 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
341 is 8-byte alignment.
342 If it is not, calculate the padding bytes. */
343 block_size = cfun->machine->fp_size
344 + cfun->machine->gp_size
345 + cfun->machine->lp_size
346 + cfun->machine->callee_saved_gpr_regs_size;
347 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
349 cfun->machine->callee_saved_area_gpr_padding_bytes
350 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
353 /* If stack usage computation is required,
354 we need to provide the static stack size. */
355 if (flag_stack_usage_info)
357 current_function_static_stack_size
358 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
359 + cfun->machine->local_size
360 + cfun->machine->out_args_size;
364 /* Function to create a parallel rtx pattern
365 which presents stack push multiple behavior.
366 The overall concept are:
367 "push registers to memory",
368 "adjust stack pointer". */
369 static void
370 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4, bool vaarg_p)
372 int regno;
373 int extra_count;
374 int num_use_regs;
375 int par_index;
376 int offset;
377 int save_fp, save_gp, save_lp;
379 rtx reg;
380 rtx mem;
381 rtx push_rtx;
382 rtx adjust_sp_rtx;
383 rtx parallel_insn;
384 rtx dwarf;
386 /* We need to provide a customized rtx which contains
387 necessary information for data analysis,
388 so we create a parallel rtx like this:
389 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
390 (reg:SI Rb))
391 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
392 (reg:SI Rb+1))
394 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
395 (reg:SI Re))
396 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
397 (reg:SI FP_REGNUM))
398 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
399 (reg:SI GP_REGNUM))
400 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
401 (reg:SI LP_REGNUM))
402 (set (reg:SI SP_REGNUM)
403 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
405 /* Determine whether we need to save $fp, $gp, or $lp. */
406 save_fp = INTVAL (En4) & 0x8;
407 save_gp = INTVAL (En4) & 0x4;
408 save_lp = INTVAL (En4) & 0x2;
410 /* Calculate the number of registers that will be pushed. */
411 extra_count = 0;
412 if (save_fp)
413 extra_count++;
414 if (save_gp)
415 extra_count++;
416 if (save_lp)
417 extra_count++;
418 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
419 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
420 num_use_regs = extra_count;
421 else
422 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
424 /* In addition to used registers,
425 we need one more space for (set sp sp-x) rtx. */
426 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
427 rtvec_alloc (num_use_regs + 1));
428 par_index = 0;
430 /* Initialize offset and start to create push behavior. */
431 offset = -(num_use_regs * 4);
433 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
434 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
436 /* Rb and Re may be SP_REGNUM.
437 We need to break this loop immediately. */
438 if (regno == SP_REGNUM)
439 break;
441 reg = gen_rtx_REG (SImode, regno);
442 mem = gen_frame_mem (SImode, plus_constant (Pmode,
443 stack_pointer_rtx,
444 offset));
445 push_rtx = gen_rtx_SET (mem, reg);
446 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
447 RTX_FRAME_RELATED_P (push_rtx) = 1;
448 offset = offset + 4;
449 par_index++;
452 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
453 if (save_fp)
455 reg = gen_rtx_REG (SImode, FP_REGNUM);
456 mem = gen_frame_mem (SImode, plus_constant (Pmode,
457 stack_pointer_rtx,
458 offset));
459 push_rtx = gen_rtx_SET (mem, reg);
460 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
461 RTX_FRAME_RELATED_P (push_rtx) = 1;
462 offset = offset + 4;
463 par_index++;
465 if (save_gp)
467 reg = gen_rtx_REG (SImode, GP_REGNUM);
468 mem = gen_frame_mem (SImode, plus_constant (Pmode,
469 stack_pointer_rtx,
470 offset));
471 push_rtx = gen_rtx_SET (mem, reg);
472 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
473 RTX_FRAME_RELATED_P (push_rtx) = 1;
474 offset = offset + 4;
475 par_index++;
477 if (save_lp)
479 reg = gen_rtx_REG (SImode, LP_REGNUM);
480 mem = gen_frame_mem (SImode, plus_constant (Pmode,
481 stack_pointer_rtx,
482 offset));
483 push_rtx = gen_rtx_SET (mem, reg);
484 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
485 RTX_FRAME_RELATED_P (push_rtx) = 1;
486 offset = offset + 4;
487 par_index++;
490 /* Create (set sp sp-x). */
492 /* We need to re-calculate the offset value again for adjustment. */
493 offset = -(num_use_regs * 4);
494 adjust_sp_rtx
495 = gen_rtx_SET (stack_pointer_rtx,
496 plus_constant (Pmode, stack_pointer_rtx, offset));
497 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
498 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
500 parallel_insn = emit_insn (parallel_insn);
502 /* The insn rtx 'parallel_insn' will change frame layout.
503 We need to use RTX_FRAME_RELATED_P so that GCC is able to
504 generate CFI (Call Frame Information) stuff. */
505 RTX_FRAME_RELATED_P (parallel_insn) = 1;
507 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
508 since we will not restore those register at epilogue. */
509 if (vaarg_p)
511 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
512 copy_rtx (adjust_sp_rtx), NULL_RTX);
513 REG_NOTES (parallel_insn) = dwarf;
517 /* Function to create a parallel rtx pattern
518 which presents stack pop multiple behavior.
519 The overall concept are:
520 "pop registers from memory",
521 "adjust stack pointer". */
522 static void
523 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
525 int regno;
526 int extra_count;
527 int num_use_regs;
528 int par_index;
529 int offset;
530 int save_fp, save_gp, save_lp;
532 rtx reg;
533 rtx mem;
534 rtx pop_rtx;
535 rtx adjust_sp_rtx;
536 rtx parallel_insn;
537 rtx dwarf = NULL_RTX;
539 /* We need to provide a customized rtx which contains
540 necessary information for data analysis,
541 so we create a parallel rtx like this:
542 (parallel [(set (reg:SI Rb)
543 (mem (reg:SI SP_REGNUM)))
544 (set (reg:SI Rb+1)
545 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
547 (set (reg:SI Re)
548 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
549 (set (reg:SI FP_REGNUM)
550 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
551 (set (reg:SI GP_REGNUM)
552 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
553 (set (reg:SI LP_REGNUM)
554 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
555 (set (reg:SI SP_REGNUM)
556 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
558 /* Determine whether we need to restore $fp, $gp, or $lp. */
559 save_fp = INTVAL (En4) & 0x8;
560 save_gp = INTVAL (En4) & 0x4;
561 save_lp = INTVAL (En4) & 0x2;
563 /* Calculate the number of registers that will be poped. */
564 extra_count = 0;
565 if (save_fp)
566 extra_count++;
567 if (save_gp)
568 extra_count++;
569 if (save_lp)
570 extra_count++;
571 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
572 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
573 num_use_regs = extra_count;
574 else
575 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
577 /* In addition to used registers,
578 we need one more space for (set sp sp+x) rtx. */
579 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
580 rtvec_alloc (num_use_regs + 1));
581 par_index = 0;
583 /* Initialize offset and start to create pop behavior. */
584 offset = 0;
586 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
587 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
589 /* Rb and Re may be SP_REGNUM.
590 We need to break this loop immediately. */
591 if (regno == SP_REGNUM)
592 break;
594 reg = gen_rtx_REG (SImode, regno);
595 mem = gen_frame_mem (SImode, plus_constant (Pmode,
596 stack_pointer_rtx,
597 offset));
598 pop_rtx = gen_rtx_SET (reg, mem);
599 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
600 RTX_FRAME_RELATED_P (pop_rtx) = 1;
601 offset = offset + 4;
602 par_index++;
604 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
607 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
608 if (save_fp)
610 reg = gen_rtx_REG (SImode, FP_REGNUM);
611 mem = gen_frame_mem (SImode, plus_constant (Pmode,
612 stack_pointer_rtx,
613 offset));
614 pop_rtx = gen_rtx_SET (reg, mem);
615 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
616 RTX_FRAME_RELATED_P (pop_rtx) = 1;
617 offset = offset + 4;
618 par_index++;
620 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
622 if (save_gp)
624 reg = gen_rtx_REG (SImode, GP_REGNUM);
625 mem = gen_frame_mem (SImode, plus_constant (Pmode,
626 stack_pointer_rtx,
627 offset));
628 pop_rtx = gen_rtx_SET (reg, mem);
629 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
630 RTX_FRAME_RELATED_P (pop_rtx) = 1;
631 offset = offset + 4;
632 par_index++;
634 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
636 if (save_lp)
638 reg = gen_rtx_REG (SImode, LP_REGNUM);
639 mem = gen_frame_mem (SImode, plus_constant (Pmode,
640 stack_pointer_rtx,
641 offset));
642 pop_rtx = gen_rtx_SET (reg, mem);
643 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
644 RTX_FRAME_RELATED_P (pop_rtx) = 1;
645 offset = offset + 4;
646 par_index++;
648 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
651 /* Create (set sp sp+x). */
653 /* The offset value is already in place. No need to re-calculate it. */
654 adjust_sp_rtx
655 = gen_rtx_SET (stack_pointer_rtx,
656 plus_constant (Pmode, stack_pointer_rtx, offset));
657 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
659 /* Tell gcc we adjust SP in this insn. */
660 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
662 parallel_insn = emit_insn (parallel_insn);
664 /* The insn rtx 'parallel_insn' will change frame layout.
665 We need to use RTX_FRAME_RELATED_P so that GCC is able to
666 generate CFI (Call Frame Information) stuff. */
667 RTX_FRAME_RELATED_P (parallel_insn) = 1;
669 /* Add CFI info by manual. */
670 REG_NOTES (parallel_insn) = dwarf;
673 /* Function to create a parallel rtx pattern
674 which presents stack v3push behavior.
675 The overall concept are:
676 "push registers to memory",
677 "adjust stack pointer". */
678 static void
679 nds32_emit_stack_v3push (rtx Rb,
680 rtx Re,
681 rtx En4 ATTRIBUTE_UNUSED,
682 rtx imm8u)
684 int regno;
685 int num_use_regs;
686 int par_index;
687 int offset;
689 rtx reg;
690 rtx mem;
691 rtx push_rtx;
692 rtx adjust_sp_rtx;
693 rtx parallel_insn;
695 /* We need to provide a customized rtx which contains
696 necessary information for data analysis,
697 so we create a parallel rtx like this:
698 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
699 (reg:SI Rb))
700 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
701 (reg:SI Rb+1))
703 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
704 (reg:SI Re))
705 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
706 (reg:SI FP_REGNUM))
707 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
708 (reg:SI GP_REGNUM))
709 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
710 (reg:SI LP_REGNUM))
711 (set (reg:SI SP_REGNUM)
712 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
714 /* Calculate the number of registers that will be pushed.
715 Since $fp, $gp, and $lp is always pushed with v3push instruction,
716 we need to count these three registers.
717 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
718 So there is no need to worry about Rb=Re=SP_REGNUM case. */
719 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
721 /* In addition to used registers,
722 we need one more space for (set sp sp-x-imm8u) rtx. */
723 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
724 rtvec_alloc (num_use_regs + 1));
725 par_index = 0;
727 /* Initialize offset and start to create push behavior. */
728 offset = -(num_use_regs * 4);
730 /* Create (set mem regX) from Rb, Rb+1 up to Re.
731 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
732 So there is no need to worry about Rb=Re=SP_REGNUM case. */
733 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
735 reg = gen_rtx_REG (SImode, regno);
736 mem = gen_frame_mem (SImode, plus_constant (Pmode,
737 stack_pointer_rtx,
738 offset));
739 push_rtx = gen_rtx_SET (mem, reg);
740 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
741 RTX_FRAME_RELATED_P (push_rtx) = 1;
742 offset = offset + 4;
743 par_index++;
746 /* Create (set mem fp). */
747 reg = gen_rtx_REG (SImode, FP_REGNUM);
748 mem = gen_frame_mem (SImode, plus_constant (Pmode,
749 stack_pointer_rtx,
750 offset));
751 push_rtx = gen_rtx_SET (mem, reg);
752 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
753 RTX_FRAME_RELATED_P (push_rtx) = 1;
754 offset = offset + 4;
755 par_index++;
756 /* Create (set mem gp). */
757 reg = gen_rtx_REG (SImode, GP_REGNUM);
758 mem = gen_frame_mem (SImode, plus_constant (Pmode,
759 stack_pointer_rtx,
760 offset));
761 push_rtx = gen_rtx_SET (mem, reg);
762 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
763 RTX_FRAME_RELATED_P (push_rtx) = 1;
764 offset = offset + 4;
765 par_index++;
766 /* Create (set mem lp). */
767 reg = gen_rtx_REG (SImode, LP_REGNUM);
768 mem = gen_frame_mem (SImode, plus_constant (Pmode,
769 stack_pointer_rtx,
770 offset));
771 push_rtx = gen_rtx_SET (mem, reg);
772 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
773 RTX_FRAME_RELATED_P (push_rtx) = 1;
774 offset = offset + 4;
775 par_index++;
777 /* Create (set sp sp-x-imm8u). */
779 /* We need to re-calculate the offset value again for adjustment. */
780 offset = -(num_use_regs * 4);
781 adjust_sp_rtx
782 = gen_rtx_SET (stack_pointer_rtx,
783 plus_constant (Pmode,
784 stack_pointer_rtx,
785 offset - INTVAL (imm8u)));
786 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
787 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
789 parallel_insn = emit_insn (parallel_insn);
791 /* The insn rtx 'parallel_insn' will change frame layout.
792 We need to use RTX_FRAME_RELATED_P so that GCC is able to
793 generate CFI (Call Frame Information) stuff. */
794 RTX_FRAME_RELATED_P (parallel_insn) = 1;
797 /* Function to create a parallel rtx pattern
798 which presents stack v3pop behavior.
799 The overall concept are:
800 "pop registers from memory",
801 "adjust stack pointer". */
802 static void
803 nds32_emit_stack_v3pop (rtx Rb,
804 rtx Re,
805 rtx En4 ATTRIBUTE_UNUSED,
806 rtx imm8u)
808 int regno;
809 int num_use_regs;
810 int par_index;
811 int offset;
813 rtx reg;
814 rtx mem;
815 rtx pop_rtx;
816 rtx adjust_sp_rtx;
817 rtx parallel_insn;
818 rtx dwarf = NULL_RTX;
820 /* We need to provide a customized rtx which contains
821 necessary information for data analysis,
822 so we create a parallel rtx like this:
823 (parallel [(set (reg:SI Rb)
824 (mem (reg:SI SP_REGNUM)))
825 (set (reg:SI Rb+1)
826 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
828 (set (reg:SI Re)
829 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
830 (set (reg:SI FP_REGNUM)
831 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
832 (set (reg:SI GP_REGNUM)
833 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
834 (set (reg:SI LP_REGNUM)
835 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
836 (set (reg:SI SP_REGNUM)
837 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
839 /* Calculate the number of registers that will be poped.
840 Since $fp, $gp, and $lp is always poped with v3pop instruction,
841 we need to count these three registers.
842 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
843 So there is no need to worry about Rb=Re=SP_REGNUM case. */
844 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
846 /* In addition to used registers,
847 we need one more space for (set sp sp+x+imm8u) rtx. */
848 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
849 rtvec_alloc (num_use_regs + 1));
850 par_index = 0;
852 /* Initialize offset and start to create pop behavior. */
853 offset = 0;
855 /* Create (set regX mem) from Rb, Rb+1 up to Re.
856 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
857 So there is no need to worry about Rb=Re=SP_REGNUM case. */
858 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
860 reg = gen_rtx_REG (SImode, regno);
861 mem = gen_frame_mem (SImode, plus_constant (Pmode,
862 stack_pointer_rtx,
863 offset));
864 pop_rtx = gen_rtx_SET (reg, mem);
865 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
866 RTX_FRAME_RELATED_P (pop_rtx) = 1;
867 offset = offset + 4;
868 par_index++;
870 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
873 /* Create (set fp mem). */
874 reg = gen_rtx_REG (SImode, FP_REGNUM);
875 mem = gen_frame_mem (SImode, plus_constant (Pmode,
876 stack_pointer_rtx,
877 offset));
878 pop_rtx = gen_rtx_SET (reg, mem);
879 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
880 RTX_FRAME_RELATED_P (pop_rtx) = 1;
881 offset = offset + 4;
882 par_index++;
883 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
885 /* Create (set gp mem). */
886 reg = gen_rtx_REG (SImode, GP_REGNUM);
887 mem = gen_frame_mem (SImode, plus_constant (Pmode,
888 stack_pointer_rtx,
889 offset));
890 pop_rtx = gen_rtx_SET (reg, mem);
891 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
892 RTX_FRAME_RELATED_P (pop_rtx) = 1;
893 offset = offset + 4;
894 par_index++;
895 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
897 /* Create (set lp mem ). */
898 reg = gen_rtx_REG (SImode, LP_REGNUM);
899 mem = gen_frame_mem (SImode, plus_constant (Pmode,
900 stack_pointer_rtx,
901 offset));
902 pop_rtx = gen_rtx_SET (reg, mem);
903 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
904 RTX_FRAME_RELATED_P (pop_rtx) = 1;
905 offset = offset + 4;
906 par_index++;
907 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
909 /* Create (set sp sp+x+imm8u). */
911 /* The offset value is already in place. No need to re-calculate it. */
912 adjust_sp_rtx
913 = gen_rtx_SET (stack_pointer_rtx,
914 plus_constant (Pmode,
915 stack_pointer_rtx,
916 offset + INTVAL (imm8u)));
917 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
919 /* Tell gcc we adjust SP in this insn. */
920 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
922 parallel_insn = emit_insn (parallel_insn);
924 /* The insn rtx 'parallel_insn' will change frame layout.
925 We need to use RTX_FRAME_RELATED_P so that GCC is able to
926 generate CFI (Call Frame Information) stuff. */
927 RTX_FRAME_RELATED_P (parallel_insn) = 1;
929 /* Add CFI info by manual. */
930 REG_NOTES (parallel_insn) = dwarf;
933 /* Function that may creates more instructions
934 for large value on adjusting stack pointer.
936 In nds32 target, 'addi' can be used for stack pointer
937 adjustment in prologue/epilogue stage.
938 However, sometimes there are too many local variables so that
939 the adjustment value is not able to be fit in the 'addi' instruction.
940 One solution is to move value into a register
941 and then use 'add' instruction.
942 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
943 Also, we need to return zero for sp adjustment so that
944 proglogue/epilogue knows there is no need to create 'addi' instruction. */
945 static int
946 nds32_force_addi_stack_int (int full_value)
948 int adjust_value;
950 rtx tmp_reg;
951 rtx sp_adjust_insn;
953 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
955 /* The value is not able to fit in single addi instruction.
956 Create more instructions of moving value into a register
957 and then add stack pointer with it. */
959 /* $r15 is going to be temporary register to hold the value. */
960 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
962 /* Create one more instruction to move value
963 into the temporary register. */
964 emit_move_insn (tmp_reg, GEN_INT (full_value));
966 /* Create new 'add' rtx. */
967 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
968 stack_pointer_rtx,
969 tmp_reg);
970 /* Emit rtx into insn list and receive its transformed insn rtx. */
971 sp_adjust_insn = emit_insn (sp_adjust_insn);
973 /* At prologue, we need to tell GCC that this is frame related insn,
974 so that we can consider this instruction to output debug information.
975 If full_value is NEGATIVE, it means this function
976 is invoked by expand_prologue. */
977 if (full_value < 0)
979 /* Because (tmp_reg <- full_value) may be split into two
980 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
981 We need to construct another (sp <- sp + full_value)
982 and then insert it into sp_adjust_insn's reg note to
983 represent a frame related expression.
984 GCC knows how to refer it and output debug information. */
986 rtx plus_rtx;
987 rtx set_rtx;
989 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
990 set_rtx = gen_rtx_SET (stack_pointer_rtx, plus_rtx);
991 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
993 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
996 /* We have used alternative way to adjust stack pointer value.
997 Return zero so that prologue/epilogue
998 will not generate other instructions. */
999 return 0;
1001 else
1003 /* The value is able to fit in addi instruction.
1004 However, remember to make it to be positive value
1005 because we want to return 'adjustment' result. */
1006 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
1008 return adjust_value;
1012 /* Return true if MODE/TYPE need double word alignment. */
1013 static bool
1014 nds32_needs_double_word_align (machine_mode mode, const_tree type)
1016 unsigned int align;
1018 /* Pick up the alignment according to the mode or type. */
1019 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1021 return (align > PARM_BOUNDARY);
1024 /* Return true if FUNC is a naked function. */
1025 static bool
1026 nds32_naked_function_p (tree func)
1028 tree t;
1030 if (TREE_CODE (func) != FUNCTION_DECL)
1031 abort ();
1033 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1035 return (t != NULL_TREE);
1038 /* Function that check if 'X' is a valid address register.
1039 The variable 'STRICT' is very important to
1040 make decision for register number.
1042 STRICT : true
1043 => We are in reload pass or after reload pass.
1044 The register number should be strictly limited in general registers.
1046 STRICT : false
1047 => Before reload pass, we are free to use any register number. */
1048 static bool
1049 nds32_address_register_rtx_p (rtx x, bool strict)
1051 int regno;
1053 if (GET_CODE (x) != REG)
1054 return false;
1056 regno = REGNO (x);
1058 if (strict)
1059 return REGNO_OK_FOR_BASE_P (regno);
1060 else
1061 return true;
1064 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1066 OUTER_MODE : Machine mode of outer address rtx.
1067 INDEX : Check if this rtx is valid to be a index for address.
1068 STRICT : If it is true, we are in reload pass or after reload pass. */
1069 static bool
1070 nds32_legitimate_index_p (machine_mode outer_mode,
1071 rtx index,
1072 bool strict)
1074 int regno;
1075 rtx op0;
1076 rtx op1;
1078 switch (GET_CODE (index))
1080 case REG:
1081 regno = REGNO (index);
1082 /* If we are in reload pass or after reload pass,
1083 we need to limit it to general register. */
1084 if (strict)
1085 return REGNO_OK_FOR_INDEX_P (regno);
1086 else
1087 return true;
1089 case CONST_INT:
1090 /* The alignment of the integer value is determined by 'outer_mode'. */
1091 if (GET_MODE_SIZE (outer_mode) == 1)
1093 /* Further check if the value is legal for the 'outer_mode'. */
1094 if (!satisfies_constraint_Is15 (index))
1095 return false;
1097 /* Pass all test, the value is valid, return true. */
1098 return true;
1100 if (GET_MODE_SIZE (outer_mode) == 2
1101 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1103 /* Further check if the value is legal for the 'outer_mode'. */
1104 if (!satisfies_constraint_Is16 (index))
1105 return false;
1107 /* Pass all test, the value is valid, return true. */
1108 return true;
1110 if (GET_MODE_SIZE (outer_mode) == 4
1111 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1113 /* Further check if the value is legal for the 'outer_mode'. */
1114 if (!satisfies_constraint_Is17 (index))
1115 return false;
1117 /* Pass all test, the value is valid, return true. */
1118 return true;
1120 if (GET_MODE_SIZE (outer_mode) == 8
1121 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1123 /* Further check if the value is legal for the 'outer_mode'. */
1124 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1125 SImode)))
1126 return false;
1128 /* Pass all test, the value is valid, return true. */
1129 return true;
1132 return false;
1134 case MULT:
1135 op0 = XEXP (index, 0);
1136 op1 = XEXP (index, 1);
1138 if (REG_P (op0) && CONST_INT_P (op1))
1140 int multiplier;
1141 multiplier = INTVAL (op1);
1143 /* We only allow (mult reg const_int_1)
1144 or (mult reg const_int_2) or (mult reg const_int_4). */
1145 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1146 return false;
1148 regno = REGNO (op0);
1149 /* Limit it in general registers if we are
1150 in reload pass or after reload pass. */
1151 if(strict)
1152 return REGNO_OK_FOR_INDEX_P (regno);
1153 else
1154 return true;
1157 return false;
1159 case ASHIFT:
1160 op0 = XEXP (index, 0);
1161 op1 = XEXP (index, 1);
1163 if (REG_P (op0) && CONST_INT_P (op1))
1165 int sv;
1166 /* op1 is already the sv value for use to do left shift. */
1167 sv = INTVAL (op1);
1169 /* We only allow (ashift reg const_int_0)
1170 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1171 if (sv != 0 && sv != 1 && sv !=2)
1172 return false;
1174 regno = REGNO (op0);
1175 /* Limit it in general registers if we are
1176 in reload pass or after reload pass. */
1177 if(strict)
1178 return REGNO_OK_FOR_INDEX_P (regno);
1179 else
1180 return true;
1183 return false;
1185 default:
1186 return false;
1190 /* ------------------------------------------------------------------------ */
1192 /* PART 3: Implement target hook stuff definitions. */
1194 /* Register Classes. */
1196 static unsigned char
1197 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1198 machine_mode mode)
1200 /* Return the maximum number of consecutive registers
1201 needed to represent "mode" in a register of "rclass". */
1202 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1205 static int
1206 nds32_register_priority (int hard_regno)
1208 /* Encourage to use r0-r7 for LRA when optimize for size. */
1209 if (optimize_size && hard_regno < 8)
1210 return 4;
1211 return 3;
1215 /* Stack Layout and Calling Conventions. */
1217 /* There are three kinds of pointer concepts using in GCC compiler:
1219 frame pointer: A pointer to the first location of local variables.
1220 stack pointer: A pointer to the top of a stack frame.
1221 argument pointer: A pointer to the incoming arguments.
1223 In nds32 target calling convention, we are using 8-byte alignment.
1224 Besides, we would like to have each stack frame of a function includes:
1226 [Block A]
1227 1. previous hard frame pointer
1228 2. return address
1229 3. callee-saved registers
1230 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1231 and save it at
1232 cfun->machine->callee_saved_area_padding_bytes)
1234 [Block B]
1235 1. local variables
1236 2. spilling location
1237 3. <padding bytes> (it will be calculated by GCC itself)
1238 4. incoming arguments
1239 5. <padding bytes> (it will be calculated by GCC itself)
1241 [Block C]
1242 1. <padding bytes> (it will be calculated by GCC itself)
1243 2. outgoing arguments
1245 We 'wrap' these blocks together with
1246 hard frame pointer ($r28) and stack pointer ($r31).
1247 By applying the basic frame/stack/argument pointers concept,
1248 the layout of a stack frame shoule be like this:
1251 old stack pointer -> ----
1252 | | \
1253 | | saved arguments for
1254 | | vararg functions
1255 | | /
1256 hard frame pointer -> --
1257 & argument pointer | | \
1258 | | previous hardware frame pointer
1259 | | return address
1260 | | callee-saved registers
1261 | | /
1262 frame pointer -> --
1263 | | \
1264 | | local variables
1265 | | and incoming arguments
1266 | | /
1268 | | \
1269 | | outgoing
1270 | | arguments
1271 | | /
1272 stack pointer -> ----
1274 $SFP and $AP are used to represent frame pointer and arguments pointer,
1275 which will be both eliminated as hard frame pointer. */
1277 /* -- Eliminating Frame Pointer and Arg Pointer. */
1279 static bool
1280 nds32_can_eliminate (const int from_reg, const int to_reg)
1282 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1283 return true;
1285 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1286 return true;
1288 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1289 return true;
1291 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1292 return true;
1294 return false;
1297 /* -- Passing Arguments in Registers. */
1299 static rtx
1300 nds32_function_arg (cumulative_args_t ca, machine_mode mode,
1301 const_tree type, bool named)
1303 unsigned int regno;
1304 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1306 /* The last time this hook is called,
1307 it is called with MODE == VOIDmode. */
1308 if (mode == VOIDmode)
1309 return NULL_RTX;
1311 /* For nameless arguments, we need to take care it individually. */
1312 if (!named)
1314 /* If we are under hard float abi, we have arguments passed on the
1315 stack and all situation can be handled by GCC itself. */
1316 if (TARGET_HARD_FLOAT)
1317 return NULL_RTX;
1319 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1321 /* If we still have enough registers to pass argument, pick up
1322 next available register number. */
1323 regno
1324 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1325 return gen_rtx_REG (mode, regno);
1328 /* No register available, return NULL_RTX.
1329 The compiler will use stack to pass argument instead. */
1330 return NULL_RTX;
1333 /* The following is to handle named argument.
1334 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1335 are different. */
1336 if (TARGET_HARD_FLOAT)
1338 /* Currently we have not implemented hard float yet. */
1339 gcc_unreachable ();
1341 else
1343 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1344 argument. Since we allow to pass argument partially in registers,
1345 we can just return it if there are still registers available. */
1346 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1348 /* Pick up the next available register number. */
1349 regno
1350 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1351 return gen_rtx_REG (mode, regno);
1356 /* No register available, return NULL_RTX.
1357 The compiler will use stack to pass argument instead. */
1358 return NULL_RTX;
1361 static bool
1362 nds32_must_pass_in_stack (machine_mode mode, const_tree type)
1364 /* Return true if a type must be passed in memory.
1365 If it is NOT using hard float abi, small aggregates can be
1366 passed in a register even we are calling a variadic function.
1367 So there is no need to take padding into consideration. */
1368 if (TARGET_HARD_FLOAT)
1369 return must_pass_in_stack_var_size_or_pad (mode, type);
1370 else
1371 return must_pass_in_stack_var_size (mode, type);
1374 static int
1375 nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
1376 tree type, bool named ATTRIBUTE_UNUSED)
1378 /* Returns the number of bytes at the beginning of an argument that
1379 must be put in registers. The value must be zero for arguments that are
1380 passed entirely in registers or that are entirely pushed on the stack.
1381 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1382 first register to be used by the caller for this argument. */
1383 unsigned int needed_reg_count;
1384 unsigned int remaining_reg_count;
1385 CUMULATIVE_ARGS *cum;
1387 cum = get_cumulative_args (ca);
1389 /* Under hard float abi, we better have argument entirely passed in
1390 registers or pushed on the stack so that we can reduce the complexity
1391 of dealing with cum->gpr_offset and cum->fpr_offset. */
1392 if (TARGET_HARD_FLOAT)
1393 return 0;
1395 /* If we have already runned out of argument registers, return zero
1396 so that the argument will be entirely pushed on the stack. */
1397 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1398 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1399 return 0;
1401 /* Calculate how many registers do we need for this argument. */
1402 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1404 /* Calculate how many argument registers have left for passing argument.
1405 Note that we should count it from next available register number. */
1406 remaining_reg_count
1407 = NDS32_MAX_GPR_REGS_FOR_ARGS
1408 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1409 - NDS32_GPR_ARG_FIRST_REGNUM);
1411 /* Note that we have to return the nubmer of bytes, not registers count. */
1412 if (needed_reg_count > remaining_reg_count)
1413 return remaining_reg_count * UNITS_PER_WORD;
1415 return 0;
1418 static void
1419 nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
1420 const_tree type, bool named)
1422 machine_mode sub_mode;
1423 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1425 if (named)
1427 /* We need to further check TYPE and MODE so that we can determine
1428 which kind of register we shall advance. */
1429 if (type && TREE_CODE (type) == COMPLEX_TYPE)
1430 sub_mode = TYPE_MODE (TREE_TYPE (type));
1431 else
1432 sub_mode = mode;
1434 /* Under hard float abi, we may advance FPR registers. */
1435 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (sub_mode) == MODE_FLOAT)
1437 /* Currently we have not implemented hard float yet. */
1438 gcc_unreachable ();
1440 else
1442 cum->gpr_offset
1443 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1444 - NDS32_GPR_ARG_FIRST_REGNUM
1445 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1448 else
1450 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1451 we can advance next register as well so that caller is
1452 able to pass arguments in registers and callee must be
1453 in charge of pushing all of them into stack. */
1454 if (!TARGET_HARD_FLOAT)
1456 cum->gpr_offset
1457 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1458 - NDS32_GPR_ARG_FIRST_REGNUM
1459 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1464 static unsigned int
1465 nds32_function_arg_boundary (machine_mode mode, const_tree type)
1467 return (nds32_needs_double_word_align (mode, type)
1468 ? NDS32_DOUBLE_WORD_ALIGNMENT
1469 : PARM_BOUNDARY);
1472 /* -- How Scalar Function Values Are Returned. */
1474 static rtx
1475 nds32_function_value (const_tree ret_type,
1476 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1477 bool outgoing ATTRIBUTE_UNUSED)
1479 machine_mode mode;
1480 int unsignedp;
1482 mode = TYPE_MODE (ret_type);
1483 unsignedp = TYPE_UNSIGNED (ret_type);
1485 mode = promote_mode (ret_type, mode, &unsignedp);
1487 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1490 static rtx
1491 nds32_libcall_value (machine_mode mode,
1492 const_rtx fun ATTRIBUTE_UNUSED)
1494 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1497 static bool
1498 nds32_function_value_regno_p (const unsigned int regno)
1500 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1503 /* -- Function Entry and Exit. */
1505 /* The content produced from this function
1506 will be placed before prologue body. */
1507 static void
1508 nds32_asm_function_prologue (FILE *file)
1510 int r;
1511 const char *func_name;
1512 tree attrs;
1513 tree name;
1515 /* All stack frame information is supposed to be
1516 already computed when expanding prologue.
1517 The result is in cfun->machine.
1518 DO NOT call nds32_compute_stack_frame() here
1519 because it may corrupt the essential information. */
1521 fprintf (file, "\t! BEGIN PROLOGUE\n");
1522 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1523 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1524 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1525 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1527 /* Use df_regs_ever_live_p() to detect if the register
1528 is ever used in the current function. */
1529 fprintf (file, "\t! registers ever_live: ");
1530 for (r = 0; r < 32; r++)
1532 if (df_regs_ever_live_p (r))
1533 fprintf (file, "%s, ", reg_names[r]);
1535 fputc ('\n', file);
1537 /* Display the attributes of this function. */
1538 fprintf (file, "\t! function attributes: ");
1539 /* Get the attributes tree list.
1540 Note that GCC builds attributes list with reverse order. */
1541 attrs = DECL_ATTRIBUTES (current_function_decl);
1543 /* If there is no any attribute, print out "None". */
1544 if (!attrs)
1545 fprintf (file, "None");
1547 /* If there are some attributes, try if we need to
1548 construct isr vector information. */
1549 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1550 nds32_construct_isr_vectors_information (attrs, func_name);
1552 /* Display all attributes of this function. */
1553 while (attrs)
1555 name = TREE_PURPOSE (attrs);
1556 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1558 /* Pick up the next attribute. */
1559 attrs = TREE_CHAIN (attrs);
1561 fputc ('\n', file);
1564 /* After rtl prologue has been expanded, this function is used. */
1565 static void
1566 nds32_asm_function_end_prologue (FILE *file)
1568 fprintf (file, "\t! END PROLOGUE\n");
1570 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1571 we can generate special directive: ".omit_fp_begin"
1572 to guide linker doing fp-as-gp optimization.
1573 However, for a naked function, which means
1574 it should not have prologue/epilogue,
1575 using fp-as-gp still requires saving $fp by push/pop behavior and
1576 there is no benefit to use fp-as-gp on such small function.
1577 So we need to make sure this function is NOT naked as well. */
1578 if (!frame_pointer_needed
1579 && !cfun->machine->naked_p
1580 && cfun->machine->fp_as_gp_p)
1582 fprintf (file, "\t! ----------------------------------------\n");
1583 fprintf (file, "\t! Guide linker to do "
1584 "link time optimization: fp-as-gp\n");
1585 fprintf (file, "\t! We add one more instruction to "
1586 "initialize $fp near to $gp location.\n");
1587 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1588 fprintf (file, "\t! this extra instruction should be "
1589 "eliminated at link stage.\n");
1590 fprintf (file, "\t.omit_fp_begin\n");
1591 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1592 fprintf (file, "\t! ----------------------------------------\n");
1596 /* Before rtl epilogue has been expanded, this function is used. */
1597 static void
1598 nds32_asm_function_begin_epilogue (FILE *file)
1600 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1601 we can generate special directive: ".omit_fp_end"
1602 to claim fp-as-gp optimization range.
1603 However, for a naked function,
1604 which means it should not have prologue/epilogue,
1605 using fp-as-gp still requires saving $fp by push/pop behavior and
1606 there is no benefit to use fp-as-gp on such small function.
1607 So we need to make sure this function is NOT naked as well. */
1608 if (!frame_pointer_needed
1609 && !cfun->machine->naked_p
1610 && cfun->machine->fp_as_gp_p)
1612 fprintf (file, "\t! ----------------------------------------\n");
1613 fprintf (file, "\t! Claim the range of fp-as-gp "
1614 "link time optimization\n");
1615 fprintf (file, "\t.omit_fp_end\n");
1616 fprintf (file, "\t! ----------------------------------------\n");
1619 fprintf (file, "\t! BEGIN EPILOGUE\n");
1622 /* The content produced from this function
1623 will be placed after epilogue body. */
1624 static void
1625 nds32_asm_function_epilogue (FILE *file)
1627 fprintf (file, "\t! END EPILOGUE\n");
1630 static void
1631 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1632 HOST_WIDE_INT delta,
1633 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1634 tree function)
1636 int this_regno;
1638 /* Make sure unwind info is emitted for the thunk if needed. */
1639 final_start_function (emit_barrier (), file, 1);
1641 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1643 : 0);
1645 if (delta != 0)
1647 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1649 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1650 this_regno, this_regno, delta);
1652 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1654 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1655 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1657 else
1659 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1660 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1661 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1665 fprintf (file, "\tb\t");
1666 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1667 fprintf (file, "\n");
1669 final_end_function ();
1672 /* -- Permitting tail calls. */
1674 /* Determine whether we need to enable warning for function return check. */
1675 static bool
1676 nds32_warn_func_return (tree decl)
1678 /* Naked functions are implemented entirely in assembly, including the
1679 return sequence, so suppress warnings about this. */
1680 return !nds32_naked_function_p (decl);
1684 /* Implementing the Varargs Macros. */
1686 static void
1687 nds32_setup_incoming_varargs (cumulative_args_t ca,
1688 machine_mode mode,
1689 tree type,
1690 int *pretend_args_size,
1691 int second_time ATTRIBUTE_UNUSED)
1693 unsigned int total_args_regs;
1694 unsigned int num_of_used_regs;
1695 unsigned int remaining_reg_count;
1696 CUMULATIVE_ARGS *cum;
1698 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1699 So that all nameless arguments are pushed by caller and all situation
1700 can be handled by GCC itself. */
1701 if (TARGET_HARD_FLOAT)
1702 return;
1704 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1705 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1706 However, for nameless(anonymous) arguments, we should push them on the
1707 stack so that all the nameless arguments appear to have been passed
1708 consecutively in the memory for accessing. Hence, we need to check and
1709 exclude the registers that are used for named arguments. */
1711 cum = get_cumulative_args (ca);
1713 /* The MODE and TYPE describe the last argument.
1714 We need those information to determine the remaining registers
1715 for varargs. */
1716 total_args_regs
1717 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
1718 num_of_used_regs
1719 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1720 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1722 remaining_reg_count = total_args_regs - num_of_used_regs;
1723 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
1725 return;
1728 static bool
1729 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1731 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1732 true for named arguments, and false for unnamed arguments. */
1733 return true;
1737 /* Trampolines for Nested Functions. */
1739 static void
1740 nds32_asm_trampoline_template (FILE *f)
1742 if (TARGET_REDUCED_REGS)
1744 /* Trampoline is not supported on reduced-set registers yet. */
1745 sorry ("a nested function is not supported for reduced registers");
1747 else
1749 asm_fprintf (f, "\t! Trampoline code template\n");
1750 asm_fprintf (f, "\t! This code fragment will be copied "
1751 "into stack on demand\n");
1753 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1754 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1755 "! load nested function address\n");
1756 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1757 "! load chain_value\n");
1758 asm_fprintf (f, "\tjr\t$r15\n");
1761 /* Preserve space ($pc + 16) for saving chain_value,
1762 nds32_trampoline_init will fill the value in this slot. */
1763 asm_fprintf (f, "\t! space for saving chain_value\n");
1764 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1766 /* Preserve space ($pc + 20) for saving nested function address,
1767 nds32_trampoline_init will fill the value in this slot. */
1768 asm_fprintf (f, "\t! space for saving nested function address\n");
1769 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1772 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1773 static void
1774 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1776 int i;
1778 /* Nested function address. */
1779 rtx fnaddr;
1780 /* The memory rtx that is going to
1781 be filled with chain_value. */
1782 rtx chain_value_mem;
1783 /* The memory rtx that is going to
1784 be filled with nested function address. */
1785 rtx nested_func_mem;
1787 /* Start address of trampoline code in stack, for doing cache sync. */
1788 rtx sync_cache_addr;
1789 /* Temporary register for sync instruction. */
1790 rtx tmp_reg;
1791 /* Instruction-cache sync instruction,
1792 requesting an argument as starting address. */
1793 rtx isync_insn;
1794 /* For convenience reason of doing comparison. */
1795 int tramp_align_in_bytes;
1797 /* Trampoline is not supported on reduced-set registers yet. */
1798 if (TARGET_REDUCED_REGS)
1799 sorry ("a nested function is not supported for reduced registers");
1801 /* STEP 1: Copy trampoline code template into stack,
1802 fill up essential data into stack. */
1804 /* Extract nested function address rtx. */
1805 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1807 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1808 We have nds32_asm_trampoline_template() to emit template pattern. */
1809 emit_block_move (m_tramp, assemble_trampoline_template (),
1810 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1812 /* After copying trampoline code into stack,
1813 fill chain_value into stack. */
1814 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1815 emit_move_insn (chain_value_mem, chain_value);
1816 /* After copying trampoline code int stack,
1817 fill nested function address into stack. */
1818 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1819 emit_move_insn (nested_func_mem, fnaddr);
1821 /* STEP 2: Sync instruction-cache. */
1823 /* We have successfully filled trampoline code into stack.
1824 However, in order to execute code in stack correctly,
1825 we must sync instruction cache. */
1826 sync_cache_addr = XEXP (m_tramp, 0);
1827 tmp_reg = gen_reg_rtx (SImode);
1828 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1830 /* Because nds32_cache_block_size is in bytes,
1831 we get trampoline alignment in bytes for convenient comparison. */
1832 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1834 if (tramp_align_in_bytes >= nds32_cache_block_size
1835 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1837 /* Under this condition, the starting address of trampoline
1838 must be aligned to the starting address of each cache block
1839 and we do not have to worry about cross-boundary issue. */
1840 for (i = 0;
1841 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1842 / nds32_cache_block_size;
1843 i++)
1845 emit_move_insn (tmp_reg,
1846 plus_constant (Pmode, sync_cache_addr,
1847 nds32_cache_block_size * i));
1848 emit_insn (isync_insn);
1851 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1853 /* The starting address of trampoline code
1854 may not be aligned to the cache block,
1855 so the trampoline code may be across two cache block.
1856 We need to sync the last element, which is 4-byte size,
1857 of trampoline template. */
1858 for (i = 0;
1859 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1860 / nds32_cache_block_size;
1861 i++)
1863 emit_move_insn (tmp_reg,
1864 plus_constant (Pmode, sync_cache_addr,
1865 nds32_cache_block_size * i));
1866 emit_insn (isync_insn);
1869 /* The last element of trampoline template is 4-byte size. */
1870 emit_move_insn (tmp_reg,
1871 plus_constant (Pmode, sync_cache_addr,
1872 TRAMPOLINE_SIZE - 4));
1873 emit_insn (isync_insn);
1875 else
1877 /* This is the simplest case.
1878 Because TRAMPOLINE_SIZE is less than or
1879 equal to nds32_cache_block_size,
1880 we can just sync start address and
1881 the last element of trampoline code. */
1883 /* Sync starting address of tampoline code. */
1884 emit_move_insn (tmp_reg, sync_cache_addr);
1885 emit_insn (isync_insn);
1886 /* Sync the last element, which is 4-byte size,
1887 of trampoline template. */
1888 emit_move_insn (tmp_reg,
1889 plus_constant (Pmode, sync_cache_addr,
1890 TRAMPOLINE_SIZE - 4));
1891 emit_insn (isync_insn);
1894 /* Set instruction serialization barrier
1895 to guarantee the correct operations. */
1896 emit_insn (gen_unspec_volatile_isb ());
1900 /* Addressing Modes. */
1902 static bool
1903 nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1905 /* For (mem:DI addr) or (mem:DF addr) case,
1906 we only allow 'addr' to be [reg], [symbol_ref],
1907 [const], or [reg + const_int] pattern. */
1908 if (mode == DImode || mode == DFmode)
1910 /* Allow [Reg + const_int] addressing mode. */
1911 if (GET_CODE (x) == PLUS)
1913 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1914 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1915 && CONST_INT_P (XEXP (x, 1)))
1916 return true;
1917 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1918 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1919 && CONST_INT_P (XEXP (x, 0)))
1920 return true;
1923 /* Now check [reg], [symbol_ref], and [const]. */
1924 if (GET_CODE (x) != REG
1925 && GET_CODE (x) != SYMBOL_REF
1926 && GET_CODE (x) != CONST)
1927 return false;
1930 /* Check if 'x' is a valid address. */
1931 switch (GET_CODE (x))
1933 case REG:
1934 /* (mem (reg A)) => [Ra] */
1935 return nds32_address_register_rtx_p (x, strict);
1937 case SYMBOL_REF:
1938 /* (mem (symbol_ref A)) => [symbol_ref] */
1939 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
1940 during or after LRA/reload phase. */
1941 if (TARGET_CMODEL_LARGE
1942 && (reload_completed
1943 || reload_in_progress
1944 || lra_in_progress))
1945 return false;
1946 /* If -mcmodel=medium and the symbol references to rodata section,
1947 the 'symbol_ref' is not a valid address during or after
1948 LRA/reload phase. */
1949 if (TARGET_CMODEL_MEDIUM
1950 && NDS32_SYMBOL_REF_RODATA_P (x)
1951 && (reload_completed
1952 || reload_in_progress
1953 || lra_in_progress))
1954 return false;
1956 return true;
1958 case CONST:
1959 /* (mem (const (...)))
1960 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1961 if (GET_CODE (XEXP (x, 0)) == PLUS)
1963 rtx plus_op = XEXP (x, 0);
1965 rtx op0 = XEXP (plus_op, 0);
1966 rtx op1 = XEXP (plus_op, 1);
1968 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1970 /* Now we see the [ + const_addr ] pattern, but we need
1971 some further checking. */
1972 /* If -mcmodel=large, the 'const_addr' is not a valid address
1973 during or after LRA/reload phase. */
1974 if (TARGET_CMODEL_LARGE
1975 && (reload_completed
1976 || reload_in_progress
1977 || lra_in_progress))
1978 return false;
1979 /* If -mcmodel=medium and the symbol references to rodata section,
1980 the 'const_addr' is not a valid address during or after
1981 LRA/reload phase. */
1982 if (TARGET_CMODEL_MEDIUM
1983 && NDS32_SYMBOL_REF_RODATA_P (op0)
1984 && (reload_completed
1985 || reload_in_progress
1986 || lra_in_progress))
1987 return false;
1989 /* At this point we can make sure 'const_addr' is a
1990 valid address. */
1991 return true;
1995 return false;
1997 case POST_MODIFY:
1998 /* (mem (post_modify (reg) (plus (reg) (reg))))
1999 => [Ra], Rb */
2000 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2001 => [Ra], const_int */
2002 if (GET_CODE (XEXP (x, 0)) == REG
2003 && GET_CODE (XEXP (x, 1)) == PLUS)
2005 rtx plus_op = XEXP (x, 1);
2007 rtx op0 = XEXP (plus_op, 0);
2008 rtx op1 = XEXP (plus_op, 1);
2010 if (nds32_address_register_rtx_p (op0, strict)
2011 && nds32_legitimate_index_p (mode, op1, strict))
2012 return true;
2013 else
2014 return false;
2017 return false;
2019 case POST_INC:
2020 case POST_DEC:
2021 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2022 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2023 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2024 We only need to deal with register Ra. */
2025 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2026 return true;
2027 else
2028 return false;
2030 case PLUS:
2031 /* (mem (plus reg const_int))
2032 => [Ra + imm] */
2033 /* (mem (plus reg reg))
2034 => [Ra + Rb] */
2035 /* (mem (plus (mult reg const_int) reg))
2036 => [Ra + Rb << sv] */
2037 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2038 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2039 return true;
2040 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2041 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2042 return true;
2043 else
2044 return false;
2046 case LO_SUM:
2047 /* (mem (lo_sum (reg) (symbol_ref))) */
2048 /* (mem (lo_sum (reg) (const))) */
2049 gcc_assert (REG_P (XEXP (x, 0)));
2050 if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
2051 || GET_CODE (XEXP (x, 1)) == CONST)
2052 return nds32_legitimate_address_p (mode, XEXP (x, 1), strict);
2053 else
2054 return false;
2056 default:
2057 return false;
2062 /* Describing Relative Costs of Operations. */
2064 static int
2065 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2066 reg_class_t from,
2067 reg_class_t to)
2069 if (from == HIGH_REGS || to == HIGH_REGS)
2070 return 6;
2072 return 2;
2075 static int
2076 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
2077 reg_class_t rclass ATTRIBUTE_UNUSED,
2078 bool in ATTRIBUTE_UNUSED)
2080 return 8;
2083 /* This target hook describes the relative costs of RTL expressions.
2084 Return 'true' when all subexpressions of x have been processed.
2085 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2086 Refer to gcc/rtlanal.c for more information. */
2087 static bool
2088 nds32_rtx_costs (rtx x,
2089 machine_mode mode,
2090 int outer_code,
2091 int opno,
2092 int *total,
2093 bool speed)
2095 return nds32_rtx_costs_impl (x, mode, outer_code, opno, total, speed);
2098 static int
2099 nds32_address_cost (rtx address,
2100 machine_mode mode,
2101 addr_space_t as,
2102 bool speed)
2104 return nds32_address_cost_impl (address, mode, as, speed);
2108 /* Dividing the Output into Sections (Texts, Data, . . . ). */
2110 /* If references to a symbol or a constant must be treated differently
2111 depending on something about the variable or function named by the symbol
2112 (such as what section it is in), we use this hook to store flags
2113 in symbol_ref rtx. */
2114 static void
2115 nds32_encode_section_info (tree decl, rtx rtl, int new_decl_p)
2117 default_encode_section_info (decl, rtl, new_decl_p);
2119 /* For the memory rtx, if it references to rodata section, we can store
2120 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
2121 nds32_legitimate_address_p() can determine how to treat such symbol_ref
2122 based on -mcmodel=X and this information. */
2123 if (MEM_P (rtl) && MEM_READONLY_P (rtl))
2125 rtx addr = XEXP (rtl, 0);
2127 if (GET_CODE (addr) == SYMBOL_REF)
2129 /* For (mem (symbol_ref X)) case. */
2130 SYMBOL_REF_FLAGS (addr) |= NDS32_SYMBOL_FLAG_RODATA;
2132 else if (GET_CODE (addr) == CONST
2133 && GET_CODE (XEXP (addr, 0)) == PLUS)
2135 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
2136 rtx plus_op = XEXP (addr, 0);
2137 rtx op0 = XEXP (plus_op, 0);
2138 rtx op1 = XEXP (plus_op, 1);
2140 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
2141 SYMBOL_REF_FLAGS (op0) |= NDS32_SYMBOL_FLAG_RODATA;
2147 /* Defining the Output Assembler Language. */
2149 /* -- The Overall Framework of an Assembler File. */
2151 static void
2152 nds32_asm_file_start (void)
2154 default_file_start ();
2156 /* Tell assembler which ABI we are using. */
2157 fprintf (asm_out_file, "\t! ABI version\n");
2158 fprintf (asm_out_file, "\t.abi_2\n");
2160 /* Tell assembler that this asm code is generated by compiler. */
2161 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2162 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2163 /* Give assembler the size of each vector for interrupt handler. */
2164 fprintf (asm_out_file, "\t! This vector size directive is required "
2165 "for checking inconsistency on interrupt handler\n");
2166 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2168 fprintf (asm_out_file, "\t! ------------------------------------\n");
2170 if (TARGET_ISA_V2)
2171 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2172 if (TARGET_ISA_V3)
2173 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2174 if (TARGET_ISA_V3M)
2175 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2177 if (TARGET_CMODEL_SMALL)
2178 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL");
2179 if (TARGET_CMODEL_MEDIUM)
2180 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "MEDIUM");
2181 if (TARGET_CMODEL_LARGE)
2182 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "LARGE");
2184 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2185 ((TARGET_BIG_ENDIAN) ? "big-endian"
2186 : "little-endian"));
2188 fprintf (asm_out_file, "\t! ------------------------------------\n");
2190 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2191 ((TARGET_CMOV) ? "Yes"
2192 : "No"));
2193 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
2194 ((TARGET_EXT_PERF) ? "Yes"
2195 : "No"));
2196 fprintf (asm_out_file, "\t! Use performance extension 2\t: %s\n",
2197 ((TARGET_EXT_PERF2) ? "Yes"
2198 : "No"));
2199 fprintf (asm_out_file, "\t! Use string extension\t\t: %s\n",
2200 ((TARGET_EXT_STRING) ? "Yes"
2201 : "No"));
2203 fprintf (asm_out_file, "\t! ------------------------------------\n");
2205 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2206 ((TARGET_V3PUSH) ? "Yes"
2207 : "No"));
2208 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2209 ((TARGET_16_BIT) ? "Yes"
2210 : "No"));
2211 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2212 ((TARGET_REDUCED_REGS) ? "Yes"
2213 : "No"));
2215 fprintf (asm_out_file, "\t! ------------------------------------\n");
2217 if (optimize_size)
2218 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
2219 else
2220 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2222 fprintf (asm_out_file, "\t! ------------------------------------\n");
2224 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2225 nds32_cache_block_size);
2227 fprintf (asm_out_file, "\t! ------------------------------------\n");
2229 nds32_asm_file_start_for_isr ();
2232 static void
2233 nds32_asm_file_end (void)
2235 nds32_asm_file_end_for_isr ();
2237 fprintf (asm_out_file, "\t! ------------------------------------\n");
2240 /* -- Output and Generation of Labels. */
2242 static void
2243 nds32_asm_globalize_label (FILE *stream, const char *name)
2245 fputs ("\t.global\t", stream);
2246 assemble_name (stream, name);
2247 fputs ("\n", stream);
2250 /* -- Output of Assembler Instructions. */
2252 static void
2253 nds32_print_operand (FILE *stream, rtx x, int code)
2255 int op_value;
2257 switch (code)
2259 case 0 :
2260 /* Do nothing special. */
2261 break;
2263 case 'V':
2264 /* 'x' is supposed to be CONST_INT, get the value. */
2265 gcc_assert (CONST_INT_P (x));
2266 op_value = INTVAL (x);
2268 /* According to the Andes architecture,
2269 the system/user register index range is 0 ~ 1023.
2270 In order to avoid conflict between user-specified-integer value
2271 and enum-specified-register value,
2272 the 'enum nds32_intrinsic_registers' value
2273 in nds32_intrinsic.h starts from 1024. */
2274 if (op_value < 1024 && op_value >= 0)
2276 /* If user gives integer value directly (0~1023),
2277 we just print out the value. */
2278 fprintf (stream, "%d", op_value);
2280 else if (op_value < 0
2281 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2282 + 1024))
2284 /* The enum index value for array size is out of range. */
2285 error ("intrinsic register index is out of range");
2287 else
2289 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2290 we can print out register name. Remember to substract 1024. */
2291 fprintf (stream, "%s",
2292 nds32_intrinsic_register_names[op_value - 1024]);
2295 /* No need to handle following process, so return immediately. */
2296 return;
2298 default :
2299 /* Unknown flag. */
2300 output_operand_lossage ("invalid operand output code");
2301 break;
2304 switch (GET_CODE (x))
2306 case LABEL_REF:
2307 case SYMBOL_REF:
2308 output_addr_const (stream, x);
2309 break;
2311 case REG:
2312 /* Forbid using static chain register ($r16)
2313 on reduced-set registers configuration. */
2314 if (TARGET_REDUCED_REGS
2315 && REGNO (x) == STATIC_CHAIN_REGNUM)
2316 sorry ("a nested function is not supported for reduced registers");
2318 /* Normal cases, print out register name. */
2319 fputs (reg_names[REGNO (x)], stream);
2320 break;
2322 case MEM:
2323 output_address (GET_MODE (x), XEXP (x, 0));
2324 break;
2326 case CODE_LABEL:
2327 case CONST_INT:
2328 case CONST:
2329 output_addr_const (stream, x);
2330 break;
2332 default:
2333 /* Generally, output_addr_const () is able to handle most cases.
2334 We want to see what CODE could appear,
2335 so we use gcc_unreachable() to stop it. */
2336 debug_rtx (x);
2337 gcc_unreachable ();
2338 break;
2342 static void
2343 nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x)
2345 rtx op0, op1;
2347 switch (GET_CODE (x))
2349 case SYMBOL_REF:
2350 case CONST:
2351 /* [ + symbol_ref] */
2352 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2353 fputs ("[ + ", stream);
2354 output_addr_const (stream, x);
2355 fputs ("]", stream);
2356 break;
2358 case REG:
2359 /* Forbid using static chain register ($r16)
2360 on reduced-set registers configuration. */
2361 if (TARGET_REDUCED_REGS
2362 && REGNO (x) == STATIC_CHAIN_REGNUM)
2363 sorry ("a nested function is not supported for reduced registers");
2365 /* [Ra] */
2366 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2367 break;
2369 case PLUS:
2370 op0 = XEXP (x, 0);
2371 op1 = XEXP (x, 1);
2373 /* Checking op0, forbid using static chain register ($r16)
2374 on reduced-set registers configuration. */
2375 if (TARGET_REDUCED_REGS
2376 && REG_P (op0)
2377 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2378 sorry ("a nested function is not supported for reduced registers");
2379 /* Checking op1, forbid using static chain register ($r16)
2380 on reduced-set registers configuration. */
2381 if (TARGET_REDUCED_REGS
2382 && REG_P (op1)
2383 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2384 sorry ("a nested function is not supported for reduced registers");
2386 if (REG_P (op0) && CONST_INT_P (op1))
2388 /* [Ra + imm] */
2389 fprintf (stream, "[%s + (%d)]",
2390 reg_names[REGNO (op0)], (int)INTVAL (op1));
2392 else if (REG_P (op0) && REG_P (op1))
2394 /* [Ra + Rb] */
2395 fprintf (stream, "[%s + %s]",
2396 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2398 else if (GET_CODE (op0) == MULT && REG_P (op1))
2400 /* [Ra + Rb << sv]
2401 From observation, the pattern looks like:
2402 (plus:SI (mult:SI (reg:SI 58)
2403 (const_int 4 [0x4]))
2404 (reg/f:SI 57)) */
2405 int sv;
2407 /* We need to set sv to output shift value. */
2408 if (INTVAL (XEXP (op0, 1)) == 1)
2409 sv = 0;
2410 else if (INTVAL (XEXP (op0, 1)) == 2)
2411 sv = 1;
2412 else if (INTVAL (XEXP (op0, 1)) == 4)
2413 sv = 2;
2414 else
2415 gcc_unreachable ();
2417 fprintf (stream, "[%s + %s << %d]",
2418 reg_names[REGNO (op1)],
2419 reg_names[REGNO (XEXP (op0, 0))],
2420 sv);
2422 else
2424 /* The control flow is not supposed to be here. */
2425 debug_rtx (x);
2426 gcc_unreachable ();
2429 break;
2431 case POST_MODIFY:
2432 /* (post_modify (regA) (plus (regA) (regB)))
2433 (post_modify (regA) (plus (regA) (const_int)))
2434 We would like to extract
2435 regA and regB (or const_int) from plus rtx. */
2436 op0 = XEXP (XEXP (x, 1), 0);
2437 op1 = XEXP (XEXP (x, 1), 1);
2439 /* Checking op0, forbid using static chain register ($r16)
2440 on reduced-set registers configuration. */
2441 if (TARGET_REDUCED_REGS
2442 && REG_P (op0)
2443 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2444 sorry ("a nested function is not supported for reduced registers");
2445 /* Checking op1, forbid using static chain register ($r16)
2446 on reduced-set registers configuration. */
2447 if (TARGET_REDUCED_REGS
2448 && REG_P (op1)
2449 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2450 sorry ("a nested function is not supported for reduced registers");
2452 if (REG_P (op0) && REG_P (op1))
2454 /* [Ra], Rb */
2455 fprintf (stream, "[%s], %s",
2456 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2458 else if (REG_P (op0) && CONST_INT_P (op1))
2460 /* [Ra], imm */
2461 fprintf (stream, "[%s], %d",
2462 reg_names[REGNO (op0)], (int)INTVAL (op1));
2464 else
2466 /* The control flow is not supposed to be here. */
2467 debug_rtx (x);
2468 gcc_unreachable ();
2471 break;
2473 case POST_INC:
2474 case POST_DEC:
2475 op0 = XEXP (x, 0);
2477 /* Checking op0, forbid using static chain register ($r16)
2478 on reduced-set registers configuration. */
2479 if (TARGET_REDUCED_REGS
2480 && REG_P (op0)
2481 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2482 sorry ("a nested function is not supported for reduced registers");
2484 if (REG_P (op0))
2486 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2487 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2488 We only need to deal with register Ra. */
2489 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2491 else
2493 /* The control flow is not supposed to be here. */
2494 debug_rtx (x);
2495 gcc_unreachable ();
2498 break;
2500 default :
2501 /* Generally, output_addr_const () is able to handle most cases.
2502 We want to see what CODE could appear,
2503 so we use gcc_unreachable() to stop it. */
2504 debug_rtx (x);
2505 gcc_unreachable ();
2506 break;
2511 /* Defining target-specific uses of __attribute__. */
2513 /* Add some checking after merging attributes. */
2514 static tree
2515 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2517 tree combined_attrs;
2519 /* Create combined attributes. */
2520 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2521 DECL_ATTRIBUTES (newdecl));
2523 /* Since newdecl is acutally a duplicate of olddecl,
2524 we can take olddecl for some operations. */
2525 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2527 /* Check isr-specific attributes conflict. */
2528 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2531 return combined_attrs;
2534 /* Add some checking when inserting attributes. */
2535 static void
2536 nds32_insert_attributes (tree decl, tree *attributes)
2538 /* For function declaration, we need to check isr-specific attributes:
2539 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2540 2. Check valid integer value for interrupt/exception.
2541 3. Check valid integer value for reset.
2542 4. Check valid function for nmi/warm. */
2543 if (TREE_CODE (decl) == FUNCTION_DECL)
2545 tree func_attrs;
2546 tree intr, excp, reset;
2548 /* Pick up function attributes. */
2549 func_attrs = *attributes;
2551 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2552 nds32_check_isr_attrs_conflict (decl, func_attrs);
2554 /* Now we are starting to check valid id value
2555 for interrupt/exception/reset.
2556 Note that we ONLY check its validity here.
2557 To construct isr vector information, it is still performed
2558 by nds32_construct_isr_vectors_information(). */
2559 intr = lookup_attribute ("interrupt", func_attrs);
2560 excp = lookup_attribute ("exception", func_attrs);
2561 reset = lookup_attribute ("reset", func_attrs);
2563 if (intr || excp)
2565 /* Deal with interrupt/exception. */
2566 tree id_list;
2567 unsigned int lower_bound, upper_bound;
2569 /* The way to handle interrupt or exception is the same,
2570 we just need to take care of actual vector number.
2571 For interrupt(0..63), the actual vector number is (9..72).
2572 For exception(1..8), the actual vector number is (1..8). */
2573 lower_bound = (intr) ? (0) : (1);
2574 upper_bound = (intr) ? (63) : (8);
2576 /* Prepare id list so that we can traverse id value. */
2577 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2579 /* 2. Check valid integer value for interrupt/exception. */
2580 while (id_list)
2582 tree id;
2584 /* Pick up each vector id value. */
2585 id = TREE_VALUE (id_list);
2586 /* Issue error if it is not a valid integer value. */
2587 if (TREE_CODE (id) != INTEGER_CST
2588 || wi::ltu_p (wi::to_wide (id), lower_bound)
2589 || wi::gtu_p (wi::to_wide (id), upper_bound))
2590 error ("invalid id value for interrupt/exception attribute");
2592 /* Advance to next id. */
2593 id_list = TREE_CHAIN (id_list);
2596 else if (reset)
2598 /* Deal with reset. */
2599 tree id_list;
2600 tree id;
2601 tree nmi, warm;
2602 unsigned int lower_bound;
2603 unsigned int upper_bound;
2605 /* Prepare id_list and identify id value so that
2606 we can check if total number of vectors is valid. */
2607 id_list = TREE_VALUE (reset);
2608 id = TREE_VALUE (id_list);
2610 /* The maximum numbers for user's interrupt is 64. */
2611 lower_bound = 0;
2612 upper_bound = 64;
2614 /* 3. Check valid integer value for reset. */
2615 if (TREE_CODE (id) != INTEGER_CST
2616 || wi::ltu_p (wi::to_wide (id), lower_bound)
2617 || wi::gtu_p (wi::to_wide (id), upper_bound))
2618 error ("invalid id value for reset attribute");
2620 /* 4. Check valid function for nmi/warm. */
2621 nmi = lookup_attribute ("nmi", func_attrs);
2622 warm = lookup_attribute ("warm", func_attrs);
2624 if (nmi != NULL_TREE)
2626 tree nmi_func_list;
2627 tree nmi_func;
2629 nmi_func_list = TREE_VALUE (nmi);
2630 nmi_func = TREE_VALUE (nmi_func_list);
2632 /* Issue error if it is not a valid nmi function. */
2633 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2634 error ("invalid nmi function for reset attribute");
2637 if (warm != NULL_TREE)
2639 tree warm_func_list;
2640 tree warm_func;
2642 warm_func_list = TREE_VALUE (warm);
2643 warm_func = TREE_VALUE (warm_func_list);
2645 /* Issue error if it is not a valid warm function. */
2646 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2647 error ("invalid warm function for reset attribute");
2650 else
2652 /* No interrupt, exception, or reset attribute is set. */
2653 return;
2658 static bool
2659 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2660 tree pop_target ATTRIBUTE_UNUSED)
2662 /* Currently, we do not parse any pragma target by ourself,
2663 so just simply return false. */
2664 return false;
2667 static void
2668 nds32_option_override (void)
2670 /* After all the command options have been parsed,
2671 we shall deal with some flags for changing compiler settings. */
2673 /* At first, we check if we have to strictly
2674 set some flags based on ISA family. */
2675 if (TARGET_ISA_V2)
2677 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2678 target_flags &= ~MASK_V3PUSH;
2680 if (TARGET_ISA_V3)
2682 /* Under V3 ISA, currently nothing should be strictly set. */
2684 if (TARGET_ISA_V3M)
2686 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2687 target_flags |= MASK_REDUCED_REGS;
2688 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
2689 target_flags &= ~MASK_EXT_PERF;
2690 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
2691 target_flags &= ~MASK_EXT_PERF2;
2692 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
2693 target_flags &= ~MASK_EXT_STRING;
2696 /* See if we are using reduced-set registers:
2697 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2698 If so, we must forbid using $r11~$r14, $r16~$r27. */
2699 if (TARGET_REDUCED_REGS)
2701 int r;
2703 /* Prevent register allocator from
2704 choosing it as doing register allocation. */
2705 for (r = 11; r <= 14; r++)
2706 fixed_regs[r] = call_used_regs[r] = 1;
2707 for (r = 16; r <= 27; r++)
2708 fixed_regs[r] = call_used_regs[r] = 1;
2711 if (!TARGET_16_BIT)
2713 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2714 target_flags &= ~MASK_V3PUSH;
2717 /* Currently, we don't support PIC code generation yet. */
2718 if (flag_pic)
2719 sorry ("position-independent code not supported");
2723 /* Miscellaneous Parameters. */
2725 static void
2726 nds32_init_builtins (void)
2728 nds32_init_builtins_impl ();
2731 static rtx
2732 nds32_expand_builtin (tree exp,
2733 rtx target,
2734 rtx subtarget,
2735 machine_mode mode,
2736 int ignore)
2738 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2742 /* ------------------------------------------------------------------------ */
2744 /* PART 4: Implemet extern function definitions,
2745 the prototype is in nds32-protos.h. */
2747 /* Defining Data Structures for Per-function Information. */
2749 void
2750 nds32_init_expanders (void)
2752 /* Arrange to initialize and mark the machine per-function status. */
2753 init_machine_status = nds32_init_machine_status;
2757 /* Register Usage. */
2759 /* -- How Values Fit in Registers. */
2761 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2763 static bool
2764 nds32_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2766 /* Restrict double-word quantities to even register pairs. */
2767 if (targetm.hard_regno_nregs (regno, mode) == 1
2768 || !((regno) & 1))
2769 return true;
2771 return false;
2774 #undef TARGET_HARD_REGNO_MODE_OK
2775 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
2777 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
2778 tie QI/HI/SI modes together. */
2780 static bool
2781 nds32_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2783 return (GET_MODE_CLASS (mode1) == MODE_INT
2784 && GET_MODE_CLASS (mode2) == MODE_INT
2785 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
2786 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
2789 #undef TARGET_MODES_TIEABLE_P
2790 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
2792 /* Register Classes. */
2794 enum reg_class
2795 nds32_regno_reg_class (int regno)
2797 /* Refer to nds32.h for more register class details. */
2799 if (regno >= 0 && regno <= 7)
2800 return LOW_REGS;
2801 else if (regno >= 8 && regno <= 11)
2802 return MIDDLE_REGS;
2803 else if (regno >= 12 && regno <= 14)
2804 return HIGH_REGS;
2805 else if (regno == 15)
2806 return R15_TA_REG;
2807 else if (regno >= 16 && regno <= 19)
2808 return MIDDLE_REGS;
2809 else if (regno >= 20 && regno <= 31)
2810 return HIGH_REGS;
2811 else if (regno == 32 || regno == 33)
2812 return FRAME_REGS;
2813 else
2814 return NO_REGS;
2818 /* Stack Layout and Calling Conventions. */
2820 /* -- Basic Stack Layout. */
2823 nds32_return_addr_rtx (int count,
2824 rtx frameaddr ATTRIBUTE_UNUSED)
2826 /* There is no way to determine the return address
2827 if frameaddr is the frame that has 'count' steps
2828 up from current frame. */
2829 if (count != 0)
2830 return NULL_RTX;
2832 /* If count == 0, it means we are at current frame,
2833 the return address is $r30 ($lp). */
2834 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2837 /* -- Eliminating Frame Pointer and Arg Pointer. */
2839 HOST_WIDE_INT
2840 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2842 HOST_WIDE_INT offset;
2844 /* Compute and setup stack frame size.
2845 The result will be in cfun->machine. */
2846 nds32_compute_stack_frame ();
2848 /* Remember to consider
2849 cfun->machine->callee_saved_area_gpr_padding_bytes
2850 when calculating offset. */
2851 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2853 offset = (cfun->machine->fp_size
2854 + cfun->machine->gp_size
2855 + cfun->machine->lp_size
2856 + cfun->machine->callee_saved_gpr_regs_size
2857 + cfun->machine->callee_saved_area_gpr_padding_bytes
2858 + cfun->machine->local_size
2859 + cfun->machine->out_args_size);
2861 else if (from_reg == ARG_POINTER_REGNUM
2862 && to_reg == HARD_FRAME_POINTER_REGNUM)
2864 offset = 0;
2866 else if (from_reg == FRAME_POINTER_REGNUM
2867 && to_reg == STACK_POINTER_REGNUM)
2869 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2871 else if (from_reg == FRAME_POINTER_REGNUM
2872 && to_reg == HARD_FRAME_POINTER_REGNUM)
2874 offset = (-1) * (cfun->machine->fp_size
2875 + cfun->machine->gp_size
2876 + cfun->machine->lp_size
2877 + cfun->machine->callee_saved_gpr_regs_size
2878 + cfun->machine->callee_saved_area_gpr_padding_bytes);
2880 else
2882 gcc_unreachable ();
2885 return offset;
2888 /* -- Passing Arguments in Registers. */
2890 void
2891 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2892 tree fntype ATTRIBUTE_UNUSED,
2893 rtx libname ATTRIBUTE_UNUSED,
2894 tree fndecl ATTRIBUTE_UNUSED,
2895 int n_named_args ATTRIBUTE_UNUSED)
2897 /* Initial available registers
2898 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2899 for passing arguments. */
2900 cum->gpr_offset = 0;
2903 /* -- Function Entry and Exit. */
2905 /* Function for normal multiple push prologue. */
2906 void
2907 nds32_expand_prologue (void)
2909 int fp_adjust;
2910 int sp_adjust;
2911 int en4_const;
2913 rtx Rb, Re;
2914 rtx fp_adjust_insn, sp_adjust_insn;
2916 /* Compute and setup stack frame size.
2917 The result will be in cfun->machine. */
2918 nds32_compute_stack_frame ();
2920 /* If this is a variadic function, first we need to push argument
2921 registers that hold the unnamed argument value. */
2922 if (cfun->machine->va_args_size != 0)
2924 Rb = gen_rtx_REG (SImode, cfun->machine->va_args_first_regno);
2925 Re = gen_rtx_REG (SImode, cfun->machine->va_args_last_regno);
2926 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2927 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (0), true);
2929 /* We may also need to adjust stack pointer for padding bytes
2930 because varargs may cause $sp not 8-byte aligned. */
2931 if (cfun->machine->va_args_area_padding_bytes)
2933 /* Generate sp adjustment instruction. */
2934 sp_adjust = cfun->machine->va_args_area_padding_bytes;
2935 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2936 stack_pointer_rtx,
2937 GEN_INT (-1 * sp_adjust));
2939 /* Emit rtx into instructions list and receive INSN rtx form. */
2940 sp_adjust_insn = emit_insn (sp_adjust_insn);
2942 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2943 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2944 generate CFI (Call Frame Information) stuff. */
2945 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2949 /* If the function is 'naked',
2950 we do not have to generate prologue code fragment. */
2951 if (cfun->machine->naked_p)
2952 return;
2954 /* Get callee_first_regno and callee_last_regno. */
2955 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno);
2956 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno);
2958 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2959 the pattern 'stack_push_multiple' is implemented in nds32.md.
2960 For En4 field, we have to calculate its constant value.
2961 Refer to Andes ISA for more information. */
2962 en4_const = 0;
2963 if (cfun->machine->fp_size)
2964 en4_const += 8;
2965 if (cfun->machine->gp_size)
2966 en4_const += 4;
2967 if (cfun->machine->lp_size)
2968 en4_const += 2;
2970 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2971 to be saved, we don't have to create multiple push instruction.
2972 Otherwise, a multiple push instruction is needed. */
2973 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2975 /* Create multiple push instruction rtx. */
2976 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const), false);
2979 /* Check frame_pointer_needed to see
2980 if we shall emit fp adjustment instruction. */
2981 if (frame_pointer_needed)
2983 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2984 + (4 * callee-saved-registers)
2985 Note: No need to adjust
2986 cfun->machine->callee_saved_area_gpr_padding_bytes,
2987 because, at this point, stack pointer is just
2988 at the position after push instruction. */
2989 fp_adjust = cfun->machine->fp_size
2990 + cfun->machine->gp_size
2991 + cfun->machine->lp_size
2992 + cfun->machine->callee_saved_gpr_regs_size;
2993 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2994 stack_pointer_rtx,
2995 GEN_INT (fp_adjust));
2996 /* Emit rtx into instructions list and receive INSN rtx form. */
2997 fp_adjust_insn = emit_insn (fp_adjust_insn);
2999 /* The insn rtx 'fp_adjust_insn' will change frame layout. */
3000 RTX_FRAME_RELATED_P (fp_adjust_insn) = 1;
3003 /* Adjust $sp = $sp - local_size - out_args_size
3004 - callee_saved_area_gpr_padding_bytes. */
3005 sp_adjust = cfun->machine->local_size
3006 + cfun->machine->out_args_size
3007 + cfun->machine->callee_saved_area_gpr_padding_bytes;
3008 /* sp_adjust value may be out of range of the addi instruction,
3009 create alternative add behavior with TA_REGNUM if necessary,
3010 using NEGATIVE value to tell that we are decreasing address. */
3011 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3012 if (sp_adjust)
3014 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
3015 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3016 stack_pointer_rtx,
3017 GEN_INT (-1 * sp_adjust));
3018 /* Emit rtx into instructions list and receive INSN rtx form. */
3019 sp_adjust_insn = emit_insn (sp_adjust_insn);
3021 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3022 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3023 generate CFI (Call Frame Information) stuff. */
3024 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3027 /* Prevent the instruction scheduler from
3028 moving instructions across the boundary. */
3029 emit_insn (gen_blockage ());
3032 /* Function for normal multiple pop epilogue. */
3033 void
3034 nds32_expand_epilogue (bool sibcall_p)
3036 int sp_adjust;
3037 int en4_const;
3039 rtx Rb, Re;
3040 rtx sp_adjust_insn;
3042 /* Compute and setup stack frame size.
3043 The result will be in cfun->machine. */
3044 nds32_compute_stack_frame ();
3046 /* Prevent the instruction scheduler from
3047 moving instructions across the boundary. */
3048 emit_insn (gen_blockage ());
3050 /* If the function is 'naked', we do not have to generate
3051 epilogue code fragment BUT 'ret' instruction.
3052 However, if this function is also a variadic function,
3053 we need to create adjust stack pointer before 'ret' instruction. */
3054 if (cfun->machine->naked_p)
3056 /* If this is a variadic function, we do not have to restore argument
3057 registers but need to adjust stack pointer back to previous stack
3058 frame location before return. */
3059 if (cfun->machine->va_args_size != 0)
3061 /* Generate sp adjustment instruction.
3062 We need to consider padding bytes here. */
3063 sp_adjust = cfun->machine->va_args_size
3064 + cfun->machine->va_args_area_padding_bytes;
3065 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3066 stack_pointer_rtx,
3067 GEN_INT (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 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3073 generate CFI (Call Frame Information) stuff. */
3074 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3077 /* Generate return instruction by using 'return_internal' pattern.
3078 Make sure this instruction is after gen_blockage(). */
3079 if (!sibcall_p)
3080 emit_jump_insn (gen_return_internal ());
3081 return;
3084 if (frame_pointer_needed)
3086 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3087 - (4 * callee-saved-registers)
3088 Note: No need to adjust
3089 cfun->machine->callee_saved_area_gpr_padding_bytes,
3090 because we want to adjust stack pointer
3091 to the position for pop instruction. */
3092 sp_adjust = cfun->machine->fp_size
3093 + cfun->machine->gp_size
3094 + cfun->machine->lp_size
3095 + cfun->machine->callee_saved_gpr_regs_size;
3096 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3097 hard_frame_pointer_rtx,
3098 GEN_INT (-1 * 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;
3105 else
3107 /* If frame pointer is NOT needed,
3108 we cannot calculate the sp adjustment from frame pointer.
3109 Instead, we calculate the adjustment by local_size,
3110 out_args_size, and callee_saved_area_padding_bytes.
3111 Notice that such sp adjustment value may be out of range,
3112 so we have to deal with it as well. */
3114 /* Adjust $sp = $sp + local_size + out_args_size
3115 + callee_saved_area_padding_bytes. */
3116 sp_adjust = cfun->machine->local_size
3117 + cfun->machine->out_args_size
3118 + cfun->machine->callee_saved_area_gpr_padding_bytes;
3119 /* sp_adjust value may be out of range of the addi instruction,
3120 create alternative add behavior with TA_REGNUM if necessary,
3121 using POSITIVE value to tell that we are increasing address. */
3122 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3123 if (sp_adjust)
3125 /* Generate sp adjustment instruction
3126 if and only if sp_adjust != 0. */
3127 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3128 stack_pointer_rtx,
3129 GEN_INT (sp_adjust));
3130 /* Emit rtx into instructions list and receive INSN rtx form. */
3131 sp_adjust_insn = emit_insn (sp_adjust_insn);
3133 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3134 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3138 /* Get callee_first_regno and callee_last_regno. */
3139 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno);
3140 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno);
3142 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3143 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3144 For En4 field, we have to calculate its constant value.
3145 Refer to Andes ISA for more information. */
3146 en4_const = 0;
3147 if (cfun->machine->fp_size)
3148 en4_const += 8;
3149 if (cfun->machine->gp_size)
3150 en4_const += 4;
3151 if (cfun->machine->lp_size)
3152 en4_const += 2;
3154 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3155 to be saved, we don't have to create multiple pop instruction.
3156 Otherwise, a multiple pop instruction is needed. */
3157 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
3159 /* Create multiple pop instruction rtx. */
3160 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
3163 /* If this is a variadic function, we do not have to restore argument
3164 registers but need to adjust stack pointer back to previous stack
3165 frame location before return. */
3166 if (cfun->machine->va_args_size != 0)
3168 /* Generate sp adjustment instruction.
3169 We need to consider padding bytes here. */
3170 sp_adjust = cfun->machine->va_args_size
3171 + cfun->machine->va_args_area_padding_bytes;
3172 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3173 stack_pointer_rtx,
3174 GEN_INT (sp_adjust));
3175 /* Emit rtx into instructions list and receive INSN rtx form. */
3176 sp_adjust_insn = emit_insn (sp_adjust_insn);
3178 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3179 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3180 generate CFI (Call Frame Information) stuff. */
3181 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3184 /* Generate return instruction. */
3185 if (!sibcall_p)
3186 emit_jump_insn (gen_return_internal ());
3189 /* Function for v3push prologue. */
3190 void
3191 nds32_expand_prologue_v3push (void)
3193 int fp_adjust;
3194 int sp_adjust;
3196 rtx Rb, Re;
3197 rtx fp_adjust_insn, sp_adjust_insn;
3199 /* Compute and setup stack frame size.
3200 The result will be in cfun->machine. */
3201 nds32_compute_stack_frame ();
3203 /* If the function is 'naked',
3204 we do not have to generate prologue code fragment. */
3205 if (cfun->machine->naked_p)
3206 return;
3208 /* Get callee_first_regno and callee_last_regno. */
3209 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno);
3210 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno);
3212 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3213 where imm8u has to be 8-byte alignment. */
3214 sp_adjust = cfun->machine->local_size
3215 + cfun->machine->out_args_size
3216 + cfun->machine->callee_saved_area_gpr_padding_bytes;
3218 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3219 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
3221 /* We can use 'push25 Re,imm8u'. */
3223 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3224 the pattern 'stack_v3push' is implemented in nds32.md.
3225 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3226 nds32_emit_stack_v3push (Rb, Re,
3227 GEN_INT (14), GEN_INT (sp_adjust));
3229 /* Check frame_pointer_needed to see
3230 if we shall emit fp adjustment instruction. */
3231 if (frame_pointer_needed)
3233 /* adjust $fp = $sp + 4 ($fp size)
3234 + 4 ($gp size)
3235 + 4 ($lp size)
3236 + (4 * n) (callee-saved registers)
3237 + sp_adjust ('push25 Re,imm8u')
3238 Note: Since we use 'push25 Re,imm8u',
3239 the position of stack pointer is further
3240 changed after push instruction.
3241 Hence, we need to take sp_adjust value
3242 into consideration. */
3243 fp_adjust = cfun->machine->fp_size
3244 + cfun->machine->gp_size
3245 + cfun->machine->lp_size
3246 + cfun->machine->callee_saved_gpr_regs_size
3247 + sp_adjust;
3248 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3249 stack_pointer_rtx,
3250 GEN_INT (fp_adjust));
3251 /* Emit rtx into instructions list and receive INSN rtx form. */
3252 fp_adjust_insn = emit_insn (fp_adjust_insn);
3255 else
3257 /* We have to use 'push25 Re,0' and
3258 expand one more instruction to adjust $sp later. */
3260 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3261 the pattern 'stack_v3push' is implemented in nds32.md.
3262 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3263 nds32_emit_stack_v3push (Rb, Re,
3264 GEN_INT (14), GEN_INT (0));
3266 /* Check frame_pointer_needed to see
3267 if we shall emit fp adjustment instruction. */
3268 if (frame_pointer_needed)
3270 /* adjust $fp = $sp + 4 ($fp size)
3271 + 4 ($gp size)
3272 + 4 ($lp size)
3273 + (4 * n) (callee-saved registers)
3274 Note: Since we use 'push25 Re,0',
3275 the stack pointer is just at the position
3276 after push instruction.
3277 No need to take sp_adjust into consideration. */
3278 fp_adjust = cfun->machine->fp_size
3279 + cfun->machine->gp_size
3280 + cfun->machine->lp_size
3281 + cfun->machine->callee_saved_gpr_regs_size;
3282 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
3283 stack_pointer_rtx,
3284 GEN_INT (fp_adjust));
3285 /* Emit rtx into instructions list and receive INSN rtx form. */
3286 fp_adjust_insn = emit_insn (fp_adjust_insn);
3289 /* Because we use 'push25 Re,0',
3290 we need to expand one more instruction to adjust $sp.
3291 However, sp_adjust value may be out of range of the addi instruction,
3292 create alternative add behavior with TA_REGNUM if necessary,
3293 using NEGATIVE value to tell that we are decreasing address. */
3294 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
3295 if (sp_adjust)
3297 /* Generate sp adjustment instruction
3298 if and only if sp_adjust != 0. */
3299 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3300 stack_pointer_rtx,
3301 GEN_INT (-1 * sp_adjust));
3302 /* Emit rtx into instructions list and receive INSN rtx form. */
3303 sp_adjust_insn = emit_insn (sp_adjust_insn);
3305 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3306 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3307 generate CFI (Call Frame Information) stuff. */
3308 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3312 /* Prevent the instruction scheduler from
3313 moving instructions across the boundary. */
3314 emit_insn (gen_blockage ());
3317 /* Function for v3pop epilogue. */
3318 void
3319 nds32_expand_epilogue_v3pop (bool sibcall_p)
3321 int sp_adjust;
3323 rtx Rb, Re;
3324 rtx sp_adjust_insn;
3326 /* Compute and setup stack frame size.
3327 The result will be in cfun->machine. */
3328 nds32_compute_stack_frame ();
3330 /* Prevent the instruction scheduler from
3331 moving instructions across the boundary. */
3332 emit_insn (gen_blockage ());
3334 /* If the function is 'naked', we do not have to generate
3335 epilogue code fragment BUT 'ret' instruction. */
3336 if (cfun->machine->naked_p)
3338 /* Generate return instruction by using 'return_internal' pattern.
3339 Make sure this instruction is after gen_blockage(). */
3340 if (!sibcall_p)
3341 emit_jump_insn (gen_return_internal ());
3342 return;
3345 /* Get callee_first_regno and callee_last_regno. */
3346 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_first_gpr_regno);
3347 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_last_gpr_regno);
3349 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3350 where imm8u has to be 8-byte alignment. */
3351 sp_adjust = cfun->machine->local_size
3352 + cfun->machine->out_args_size
3353 + cfun->machine->callee_saved_area_gpr_padding_bytes;
3355 /* We have to consider alloca issue as well.
3356 If the function does call alloca(), the stack pointer is not fixed.
3357 In that case, we cannot use 'pop25 Re,imm8u' directly.
3358 We have to caculate stack pointer from frame pointer
3359 and then use 'pop25 Re,0'.
3360 Of course, the frame_pointer_needed should be nonzero
3361 if the function calls alloca(). */
3362 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3363 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3364 && !cfun->calls_alloca)
3366 /* We can use 'pop25 Re,imm8u'. */
3368 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3369 the pattern 'stack_v3pop' is implementad in nds32.md.
3370 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3371 nds32_emit_stack_v3pop (Rb, Re,
3372 GEN_INT (14), GEN_INT (sp_adjust));
3374 else
3376 /* We have to use 'pop25 Re,0', and prior to it,
3377 we must expand one more instruction to adjust $sp. */
3379 if (frame_pointer_needed)
3381 /* adjust $sp = $fp - 4 ($fp size)
3382 - 4 ($gp size)
3383 - 4 ($lp size)
3384 - (4 * n) (callee-saved registers)
3385 Note: No need to adjust
3386 cfun->machine->callee_saved_area_gpr_padding_bytes,
3387 because we want to adjust stack pointer
3388 to the position for pop instruction. */
3389 sp_adjust = cfun->machine->fp_size
3390 + cfun->machine->gp_size
3391 + cfun->machine->lp_size
3392 + cfun->machine->callee_saved_gpr_regs_size;
3393 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3394 hard_frame_pointer_rtx,
3395 GEN_INT (-1 * sp_adjust));
3396 /* Emit rtx into instructions list and receive INSN rtx form. */
3397 sp_adjust_insn = emit_insn (sp_adjust_insn);
3399 else
3401 /* If frame pointer is NOT needed,
3402 we cannot calculate the sp adjustment from frame pointer.
3403 Instead, we calculate the adjustment by local_size,
3404 out_args_size, and callee_saved_area_padding_bytes.
3405 Notice that such sp adjustment value may be out of range,
3406 so we have to deal with it as well. */
3408 /* Adjust $sp = $sp + local_size + out_args_size
3409 + callee_saved_area_gpr_padding_bytes. */
3410 sp_adjust = cfun->machine->local_size
3411 + cfun->machine->out_args_size
3412 + cfun->machine->callee_saved_area_gpr_padding_bytes;
3413 /* sp_adjust value may be out of range of the addi instruction,
3414 create alternative add behavior with TA_REGNUM if necessary,
3415 using POSITIVE value to tell that we are increasing address. */
3416 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3417 if (sp_adjust)
3419 /* Generate sp adjustment instruction
3420 if and only if sp_adjust != 0. */
3421 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3422 stack_pointer_rtx,
3423 GEN_INT (sp_adjust));
3424 /* Emit rtx into instructions list and receive INSN rtx form. */
3425 sp_adjust_insn = emit_insn (sp_adjust_insn);
3429 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3430 the pattern 'stack_v3pop' is implementad in nds32.md. */
3431 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3432 nds32_emit_stack_v3pop (Rb, Re,
3433 GEN_INT (14), GEN_INT (0));
3436 /* Generate return instruction. */
3437 emit_jump_insn (gen_pop25return ());
3440 /* Return nonzero if this function is known to have a null epilogue.
3441 This allows the optimizer to omit jumps to jumps if no stack
3442 was created. */
3444 nds32_can_use_return_insn (void)
3446 /* Prior to reloading, we can't tell how many registers must be saved.
3447 Thus we can not determine whether this function has null epilogue. */
3448 if (!reload_completed)
3449 return 0;
3451 /* If no stack was created, two conditions must be satisfied:
3452 1. This is a naked function.
3453 So there is no callee-saved, local size, or outgoing size.
3454 2. This is NOT a variadic function.
3455 So there is no pushing arguement registers into the stack. */
3456 return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0));
3459 /* ------------------------------------------------------------------------ */
3461 /* Function to test 333-form for load/store instructions.
3462 This is auxiliary extern function for auxiliary macro in nds32.h.
3463 Because it is a little complicated, we use function instead of macro. */
3464 bool
3465 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
3467 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3468 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3470 if (GET_MODE_SIZE (mode) == 4)
3471 return satisfies_constraint_Iu05 (imm);
3473 if (GET_MODE_SIZE (mode) == 2)
3474 return satisfies_constraint_Iu04 (imm);
3476 if (GET_MODE_SIZE (mode) == 1)
3477 return satisfies_constraint_Iu03 (imm);
3480 return false;
3484 /* Computing the Length of an Insn.
3485 Modifies the length assigned to instruction INSN.
3486 LEN is the initially computed length of the insn. */
3488 nds32_adjust_insn_length (rtx_insn *insn, int length)
3490 rtx src, dst;
3492 switch (recog_memoized (insn))
3494 case CODE_FOR_move_df:
3495 case CODE_FOR_move_di:
3496 /* Adjust length of movd44 to 2. */
3497 src = XEXP (PATTERN (insn), 1);
3498 dst = XEXP (PATTERN (insn), 0);
3500 if (REG_P (src)
3501 && REG_P (dst)
3502 && (REGNO (src) % 2) == 0
3503 && (REGNO (dst) % 2) == 0)
3504 length = 2;
3505 break;
3507 default:
3508 break;
3511 return length;
3515 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3517 nds32_target_alignment (rtx_insn *label)
3519 rtx_insn *insn;
3521 if (optimize_size)
3522 return 0;
3524 insn = next_active_insn (label);
3526 if (insn == 0)
3527 return 0;
3528 else if ((get_attr_length (insn) % 4) == 0)
3529 return 2;
3530 else
3531 return 0;
3534 /* ------------------------------------------------------------------------ */
3536 /* PART 5: Initialize target hook structure and definitions. */
3538 /* Controlling the Compilation Driver. */
3541 /* Run-time Target Specification. */
3544 /* Defining Data Structures for Per-function Information. */
3547 /* Storage Layout. */
3549 #undef TARGET_PROMOTE_FUNCTION_MODE
3550 #define TARGET_PROMOTE_FUNCTION_MODE \
3551 default_promote_function_mode_always_promote
3554 /* Layout of Source Language Data Types. */
3557 /* Register Usage. */
3559 /* -- Basic Characteristics of Registers. */
3561 /* -- Order of Allocation of Registers. */
3563 /* -- How Values Fit in Registers. */
3565 /* -- Handling Leaf Functions. */
3567 /* -- Registers That Form a Stack. */
3570 /* Register Classes. */
3572 #undef TARGET_CLASS_MAX_NREGS
3573 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3575 #undef TARGET_REGISTER_PRIORITY
3576 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3579 /* Obsolete Macros for Defining Constraints. */
3582 /* Stack Layout and Calling Conventions. */
3584 /* -- Basic Stack Layout. */
3586 /* -- Exception Handling Support. */
3588 /* -- Specifying How Stack Checking is Done. */
3590 /* -- Registers That Address the Stack Frame. */
3592 /* -- Eliminating Frame Pointer and Arg Pointer. */
3594 #undef TARGET_CAN_ELIMINATE
3595 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3597 /* -- Passing Function Arguments on the Stack. */
3599 /* -- Passing Arguments in Registers. */
3601 #undef TARGET_FUNCTION_ARG
3602 #define TARGET_FUNCTION_ARG nds32_function_arg
3604 #undef TARGET_MUST_PASS_IN_STACK
3605 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3607 #undef TARGET_ARG_PARTIAL_BYTES
3608 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3610 #undef TARGET_FUNCTION_ARG_ADVANCE
3611 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3613 #undef TARGET_FUNCTION_ARG_BOUNDARY
3614 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3616 /* -- How Scalar Function Values Are Returned. */
3618 #undef TARGET_FUNCTION_VALUE
3619 #define TARGET_FUNCTION_VALUE nds32_function_value
3621 #undef TARGET_LIBCALL_VALUE
3622 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3624 #undef TARGET_FUNCTION_VALUE_REGNO_P
3625 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3627 /* -- How Large Values Are Returned. */
3629 /* -- Caller-Saves Register Allocation. */
3631 /* -- Function Entry and Exit. */
3633 #undef TARGET_ASM_FUNCTION_PROLOGUE
3634 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3636 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3637 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3639 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3640 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3642 #undef TARGET_ASM_FUNCTION_EPILOGUE
3643 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3645 #undef TARGET_ASM_OUTPUT_MI_THUNK
3646 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3648 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3649 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3651 /* -- Generating Code for Profiling. */
3653 /* -- Permitting tail calls. */
3655 #undef TARGET_WARN_FUNC_RETURN
3656 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3658 /* Stack smashing protection. */
3661 /* Implementing the Varargs Macros. */
3663 #undef TARGET_SETUP_INCOMING_VARARGS
3664 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3666 #undef TARGET_STRICT_ARGUMENT_NAMING
3667 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3670 /* Trampolines for Nested Functions. */
3672 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3673 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3675 #undef TARGET_TRAMPOLINE_INIT
3676 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3679 /* Implicit Calls to Library Routines. */
3682 /* Addressing Modes. */
3684 #undef TARGET_LEGITIMATE_ADDRESS_P
3685 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3688 /* Anchored Addresses. */
3691 /* Condition Code Status. */
3693 /* -- Representation of condition codes using (cc0). */
3695 /* -- Representation of condition codes using registers. */
3697 /* -- Macros to control conditional execution. */
3700 /* Describing Relative Costs of Operations. */
3702 #undef TARGET_REGISTER_MOVE_COST
3703 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3705 #undef TARGET_MEMORY_MOVE_COST
3706 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3708 #undef TARGET_RTX_COSTS
3709 #define TARGET_RTX_COSTS nds32_rtx_costs
3711 #undef TARGET_ADDRESS_COST
3712 #define TARGET_ADDRESS_COST nds32_address_cost
3715 /* Adjusting the Instruction Scheduler. */
3718 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3720 #undef TARGET_ENCODE_SECTION_INFO
3721 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
3724 /* Position Independent Code. */
3727 /* Defining the Output Assembler Language. */
3729 /* -- The Overall Framework of an Assembler File. */
3731 #undef TARGET_ASM_FILE_START
3732 #define TARGET_ASM_FILE_START nds32_asm_file_start
3733 #undef TARGET_ASM_FILE_END
3734 #define TARGET_ASM_FILE_END nds32_asm_file_end
3736 /* -- Output of Data. */
3738 #undef TARGET_ASM_ALIGNED_HI_OP
3739 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3741 #undef TARGET_ASM_ALIGNED_SI_OP
3742 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3744 /* -- Output of Uninitialized Variables. */
3746 /* -- Output and Generation of Labels. */
3748 #undef TARGET_ASM_GLOBALIZE_LABEL
3749 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3751 /* -- How Initialization Functions Are Handled. */
3753 /* -- Macros Controlling Initialization Routines. */
3755 /* -- Output of Assembler Instructions. */
3757 #undef TARGET_PRINT_OPERAND
3758 #define TARGET_PRINT_OPERAND nds32_print_operand
3759 #undef TARGET_PRINT_OPERAND_ADDRESS
3760 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3762 /* -- Output of Dispatch Tables. */
3764 /* -- Assembler Commands for Exception Regions. */
3766 /* -- Assembler Commands for Alignment. */
3769 /* Controlling Debugging Information Format. */
3771 /* -- Macros Affecting All Debugging Formats. */
3773 /* -- Specific Options for DBX Output. */
3775 /* -- Open-Ended Hooks for DBX Format. */
3777 /* -- File Names in DBX Format. */
3779 /* -- Macros for DWARF Output. */
3781 /* -- Macros for VMS Debug Format. */
3784 /* Cross Compilation and Floating Point. */
3787 /* Mode Switching Instructions. */
3790 /* Defining target-specific uses of __attribute__. */
3792 #undef TARGET_ATTRIBUTE_TABLE
3793 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3795 #undef TARGET_MERGE_DECL_ATTRIBUTES
3796 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3798 #undef TARGET_INSERT_ATTRIBUTES
3799 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3801 #undef TARGET_OPTION_PRAGMA_PARSE
3802 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3804 #undef TARGET_OPTION_OVERRIDE
3805 #define TARGET_OPTION_OVERRIDE nds32_option_override
3808 /* Emulating TLS. */
3811 /* Defining coprocessor specifics for MIPS targets. */
3814 /* Parameters for Precompiled Header Validity Checking. */
3817 /* C++ ABI parameters. */
3820 /* Adding support for named address spaces. */
3823 /* Miscellaneous Parameters. */
3825 #undef TARGET_INIT_BUILTINS
3826 #define TARGET_INIT_BUILTINS nds32_init_builtins
3828 #undef TARGET_EXPAND_BUILTIN
3829 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3832 /* ------------------------------------------------------------------------ */
3834 /* Initialize the GCC target structure. */
3836 struct gcc_target targetm = TARGET_INITIALIZER;
3838 /* ------------------------------------------------------------------------ */