1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
25 #include "coretypes.h"
30 #include "double-int.h"
37 #include "stor-layout.h"
42 #include "hard-reg-set.h"
43 #include "insn-config.h" /* Required by recog.h. */
44 #include "conditions.h"
46 #include "insn-attr.h" /* For DFA state_t. */
47 #include "insn-codes.h" /* For CODE_FOR_xxx. */
48 #include "reload.h" /* For push_reload(). */
52 #include "statistics.h"
54 #include "fixed-value.h"
55 #include "insn-config.h"
63 #include "diagnostic-core.h"
64 #include "dominance.h"
70 #include "cfgcleanup.h"
72 #include "basic-block.h"
75 #include "tm-constrs.h"
76 #include "optabs.h" /* For GEN_FCN. */
78 #include "target-def.h"
79 #include "langhooks.h" /* For add_builtin_function(). */
83 /* ------------------------------------------------------------------------ */
85 /* This file is divided into five parts:
87 PART 1: Auxiliary static variable definitions and
88 target hook static variable definitions.
90 PART 2: Auxiliary static function definitions.
92 PART 3: Implement target hook stuff definitions.
94 PART 4: Implemet extern function definitions,
95 the prototype is in nds32-protos.h.
97 PART 5: Initialize target hook structure and definitions. */
99 /* ------------------------------------------------------------------------ */
101 /* PART 1: Auxiliary static variable definitions and
102 target hook static variable definitions. */
104 /* Define intrinsic register names.
105 Please refer to nds32_intrinsic.h file, the index is corresponding to
106 'enum nds32_intrinsic_registers' data type values.
107 NOTE that the base value starting from 1024. */
108 static const char * const nds32_intrinsic_register_names
[] =
110 "$PSW", "$IPSW", "$ITYPE", "$IPC"
113 /* Defining target-specific uses of __attribute__. */
114 static const struct attribute_spec nds32_attribute_table
[] =
116 /* Syntax: { name, min_len, max_len, decl_required, type_required,
117 function_type_required, handler, affects_type_identity } */
119 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
120 { "interrupt", 1, 64, false, false, false, NULL
, false },
121 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
122 { "exception", 1, 8, false, false, false, NULL
, false },
123 /* Argument is user's interrupt numbers. The vector number is always 0. */
124 { "reset", 1, 1, false, false, false, NULL
, false },
126 /* The attributes describing isr nested type. */
127 { "nested", 0, 0, false, false, false, NULL
, false },
128 { "not_nested", 0, 0, false, false, false, NULL
, false },
129 { "nested_ready", 0, 0, false, false, false, NULL
, false },
131 /* The attributes describing isr register save scheme. */
132 { "save_all", 0, 0, false, false, false, NULL
, false },
133 { "partial_save", 0, 0, false, false, false, NULL
, false },
135 /* The attributes used by reset attribute. */
136 { "nmi", 1, 1, false, false, false, NULL
, false },
137 { "warm", 1, 1, false, false, false, NULL
, false },
139 /* The attribute telling no prologue/epilogue. */
140 { "naked", 0, 0, false, false, false, NULL
, false },
142 /* The last attribute spec is set to be NULL. */
143 { NULL
, 0, 0, false, false, false, NULL
, false }
147 /* ------------------------------------------------------------------------ */
149 /* PART 2: Auxiliary static function definitions. */
151 /* Function to save and restore machine-specific function data. */
152 static struct machine_function
*
153 nds32_init_machine_status (void)
155 struct machine_function
*machine
;
156 machine
= ggc_cleared_alloc
<machine_function
> ();
158 /* Initially assume this function needs prologue/epilogue. */
159 machine
->naked_p
= 0;
161 /* Initially assume this function does NOT use fp_as_gp optimization. */
162 machine
->fp_as_gp_p
= 0;
167 /* Function to compute stack frame size and
168 store into cfun->machine structure. */
170 nds32_compute_stack_frame (void)
175 /* Because nds32_compute_stack_frame() will be called from different place,
176 everytime we enter this function, we have to assume this function
177 needs prologue/epilogue. */
178 cfun
->machine
->naked_p
= 0;
180 /* Get variadic arguments size to prepare pretend arguments and
181 we will push them into stack at prologue by ourself. */
182 cfun
->machine
->va_args_size
= crtl
->args
.pretend_args_size
;
183 if (cfun
->machine
->va_args_size
!= 0)
185 cfun
->machine
->va_args_first_regno
186 = NDS32_GPR_ARG_FIRST_REGNUM
187 + NDS32_MAX_GPR_REGS_FOR_ARGS
188 - (crtl
->args
.pretend_args_size
/ UNITS_PER_WORD
);
189 cfun
->machine
->va_args_last_regno
190 = NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
- 1;
194 cfun
->machine
->va_args_first_regno
= SP_REGNUM
;
195 cfun
->machine
->va_args_last_regno
= SP_REGNUM
;
198 /* Important: We need to make sure that varargs area is 8-byte alignment. */
199 block_size
= cfun
->machine
->va_args_size
;
200 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
202 cfun
->machine
->va_args_area_padding_bytes
203 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
206 /* Get local variables, incoming variables, and temporary variables size.
207 Note that we need to make sure it is 8-byte alignment because
208 there may be no padding bytes if we are using LRA. */
209 cfun
->machine
->local_size
= NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
211 /* Get outgoing arguments size. */
212 cfun
->machine
->out_args_size
= crtl
->outgoing_args_size
;
214 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
215 Check whether $fp is ever live. */
216 cfun
->machine
->fp_size
= (df_regs_ever_live_p (FP_REGNUM
)) ? 4 : 0;
218 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
219 Check whether we are using PIC code genration. */
220 cfun
->machine
->gp_size
= (flag_pic
) ? 4 : 0;
222 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
223 Check whether $lp is ever live. */
224 cfun
->machine
->lp_size
= (df_regs_ever_live_p (LP_REGNUM
)) ? 4 : 0;
226 /* Initially there is no padding bytes. */
227 cfun
->machine
->callee_saved_area_gpr_padding_bytes
= 0;
229 /* Calculate the bytes of saving callee-saved registers on stack. */
230 cfun
->machine
->callee_saved_gpr_regs_size
= 0;
231 cfun
->machine
->callee_saved_first_gpr_regno
= SP_REGNUM
;
232 cfun
->machine
->callee_saved_last_gpr_regno
= SP_REGNUM
;
233 /* Currently, there is no need to check $r28~$r31
234 because we will save them in another way. */
235 for (r
= 0; r
< 28; r
++)
237 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
239 /* Mark the first required callee-saved register
240 (only need to set it once).
241 If first regno == SP_REGNUM, we can tell that
242 it is the first time to be here. */
243 if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
244 cfun
->machine
->callee_saved_first_gpr_regno
= r
;
245 /* Mark the last required callee-saved register. */
246 cfun
->machine
->callee_saved_last_gpr_regno
= r
;
250 /* Check if this function can omit prologue/epilogue code fragment.
251 If there is 'naked' attribute in this function,
252 we can set 'naked_p' flag to indicate that
253 we do not have to generate prologue/epilogue.
254 Or, if all the following conditions succeed,
255 we can set this function 'naked_p' as well:
256 condition 1: first_regno == last_regno == SP_REGNUM,
257 which means we do not have to save
258 any callee-saved registers.
259 condition 2: Both $lp and $fp are NOT live in this function,
260 which means we do not need to save them and there
262 condition 3: There is no local_size, which means
263 we do not need to adjust $sp. */
264 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
))
265 || (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
266 && cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
267 && !df_regs_ever_live_p (FP_REGNUM
)
268 && !df_regs_ever_live_p (LP_REGNUM
)
269 && cfun
->machine
->local_size
== 0))
271 /* Set this function 'naked_p' and other functions can check this flag.
272 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
273 callee-saved, local size, and outgoing size.
274 The varargs space and ret instruction may still present in
275 the prologue/epilogue expanding. */
276 cfun
->machine
->naked_p
= 1;
278 /* No need to save $fp, $gp, and $lp.
279 We should set these value to be zero
280 so that nds32_initial_elimination_offset() can work properly. */
281 cfun
->machine
->fp_size
= 0;
282 cfun
->machine
->gp_size
= 0;
283 cfun
->machine
->lp_size
= 0;
285 /* If stack usage computation is required,
286 we need to provide the static stack size. */
287 if (flag_stack_usage_info
)
288 current_function_static_stack_size
= 0;
290 /* No need to do following adjustment, return immediately. */
294 /* Adjustment for v3push instructions:
295 If we are using v3push (push25/pop25) instructions,
296 we need to make sure Rb is $r6 and Re is
297 located on $r6, $r8, $r10, or $r14.
298 Some results above will be discarded and recomputed.
299 Note that it is only available under V3/V3M ISA and we
300 DO NOT setup following stuff for isr or variadic function. */
302 && !nds32_isr_function_p (current_function_decl
)
303 && (cfun
->machine
->va_args_size
== 0))
306 cfun->machine->fp_size
307 cfun->machine->gp_size
308 cfun->machine->lp_size
309 cfun->machine->callee_saved_regs_first_regno
310 cfun->machine->callee_saved_regs_last_regno */
312 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
313 cfun
->machine
->fp_size
= 4;
314 cfun
->machine
->gp_size
= 4;
315 cfun
->machine
->lp_size
= 4;
317 /* Remember to set Rb = $r6. */
318 cfun
->machine
->callee_saved_first_gpr_regno
= 6;
320 if (cfun
->machine
->callee_saved_last_gpr_regno
<= 6)
323 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
325 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 8)
328 cfun
->machine
->callee_saved_last_gpr_regno
= 8;
330 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 10)
333 cfun
->machine
->callee_saved_last_gpr_regno
= 10;
335 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 14)
338 cfun
->machine
->callee_saved_last_gpr_regno
= 14;
340 else if (cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
)
342 /* If last_regno is SP_REGNUM, which means
343 it is never changed, so set it to Re = $r6. */
344 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
348 /* The program flow should not go here. */
353 /* We have correctly set callee_saved_regs_first_regno
354 and callee_saved_regs_last_regno.
355 Initially, the callee_saved_regs_size is supposed to be 0.
356 As long as callee_saved_regs_last_regno is not SP_REGNUM,
357 we can update callee_saved_regs_size with new size. */
358 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
360 /* Compute pushed size of callee-saved registers. */
361 cfun
->machine
->callee_saved_gpr_regs_size
362 = 4 * (cfun
->machine
->callee_saved_last_gpr_regno
363 - cfun
->machine
->callee_saved_first_gpr_regno
367 /* Important: We need to make sure that
368 (fp_size + gp_size + lp_size + callee_saved_regs_size)
370 If it is not, calculate the padding bytes. */
371 block_size
= cfun
->machine
->fp_size
372 + cfun
->machine
->gp_size
373 + cfun
->machine
->lp_size
374 + cfun
->machine
->callee_saved_gpr_regs_size
;
375 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
377 cfun
->machine
->callee_saved_area_gpr_padding_bytes
378 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
381 /* If stack usage computation is required,
382 we need to provide the static stack size. */
383 if (flag_stack_usage_info
)
385 current_function_static_stack_size
386 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
)
387 + cfun
->machine
->local_size
388 + cfun
->machine
->out_args_size
;
392 /* Function to create a parallel rtx pattern
393 which presents stack push multiple behavior.
394 The overall concept are:
395 "push registers to memory",
396 "adjust stack pointer". */
398 nds32_emit_stack_push_multiple (rtx Rb
, rtx Re
, rtx En4
, bool vaarg_p
)
405 int save_fp
, save_gp
, save_lp
;
414 /* We need to provide a customized rtx which contains
415 necessary information for data analysis,
416 so we create a parallel rtx like this:
417 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
419 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
422 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
424 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
426 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
428 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
430 (set (reg:SI SP_REGNUM)
431 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
433 /* Determine whether we need to save $fp, $gp, or $lp. */
434 save_fp
= INTVAL (En4
) & 0x8;
435 save_gp
= INTVAL (En4
) & 0x4;
436 save_lp
= INTVAL (En4
) & 0x2;
438 /* Calculate the number of registers that will be pushed. */
446 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
447 if (REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
)
448 num_use_regs
= extra_count
;
450 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + extra_count
;
452 /* In addition to used registers,
453 we need one more space for (set sp sp-x) rtx. */
454 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
455 rtvec_alloc (num_use_regs
+ 1));
458 /* Initialize offset and start to create push behavior. */
459 offset
= -(num_use_regs
* 4);
461 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
462 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
464 /* Rb and Re may be SP_REGNUM.
465 We need to break this loop immediately. */
466 if (regno
== SP_REGNUM
)
469 reg
= gen_rtx_REG (SImode
, regno
);
470 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
473 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
474 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
475 RTX_FRAME_RELATED_P (push_rtx
) = 1;
480 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
483 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
484 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
487 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
488 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
489 RTX_FRAME_RELATED_P (push_rtx
) = 1;
495 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
496 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
499 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
500 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
501 RTX_FRAME_RELATED_P (push_rtx
) = 1;
507 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
508 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
511 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
512 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
513 RTX_FRAME_RELATED_P (push_rtx
) = 1;
518 /* Create (set sp sp-x). */
520 /* We need to re-calculate the offset value again for adjustment. */
521 offset
= -(num_use_regs
* 4);
523 = gen_rtx_SET (VOIDmode
,
525 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
526 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
527 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
529 parallel_insn
= emit_insn (parallel_insn
);
531 /* The insn rtx 'parallel_insn' will change frame layout.
532 We need to use RTX_FRAME_RELATED_P so that GCC is able to
533 generate CFI (Call Frame Information) stuff. */
534 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
536 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
537 since we will not restore those register at epilogue. */
540 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
541 copy_rtx (adjust_sp_rtx
), NULL_RTX
);
542 REG_NOTES (parallel_insn
) = dwarf
;
546 /* Function to create a parallel rtx pattern
547 which presents stack pop multiple behavior.
548 The overall concept are:
549 "pop registers from memory",
550 "adjust stack pointer". */
552 nds32_emit_stack_pop_multiple (rtx Rb
, rtx Re
, rtx En4
)
559 int save_fp
, save_gp
, save_lp
;
566 rtx dwarf
= NULL_RTX
;
568 /* We need to provide a customized rtx which contains
569 necessary information for data analysis,
570 so we create a parallel rtx like this:
571 (parallel [(set (reg:SI Rb)
572 (mem (reg:SI SP_REGNUM)))
574 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
577 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
578 (set (reg:SI FP_REGNUM)
579 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
580 (set (reg:SI GP_REGNUM)
581 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
582 (set (reg:SI LP_REGNUM)
583 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
584 (set (reg:SI SP_REGNUM)
585 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
587 /* Determine whether we need to restore $fp, $gp, or $lp. */
588 save_fp
= INTVAL (En4
) & 0x8;
589 save_gp
= INTVAL (En4
) & 0x4;
590 save_lp
= INTVAL (En4
) & 0x2;
592 /* Calculate the number of registers that will be poped. */
600 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
601 if (REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
)
602 num_use_regs
= extra_count
;
604 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + extra_count
;
606 /* In addition to used registers,
607 we need one more space for (set sp sp+x) rtx. */
608 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
609 rtvec_alloc (num_use_regs
+ 1));
612 /* Initialize offset and start to create pop behavior. */
615 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
616 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
618 /* Rb and Re may be SP_REGNUM.
619 We need to break this loop immediately. */
620 if (regno
== SP_REGNUM
)
623 reg
= gen_rtx_REG (SImode
, regno
);
624 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
627 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
628 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
629 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
633 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
636 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
639 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
640 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
643 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
644 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
645 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
649 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
653 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
654 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
657 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
658 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
659 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
663 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
667 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
668 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
671 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
672 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
673 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
677 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
680 /* Create (set sp sp+x). */
682 /* The offset value is already in place. No need to re-calculate it. */
684 = gen_rtx_SET (VOIDmode
,
686 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
687 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
689 /* Tell gcc we adjust SP in this insn. */
690 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
692 parallel_insn
= emit_insn (parallel_insn
);
694 /* The insn rtx 'parallel_insn' will change frame layout.
695 We need to use RTX_FRAME_RELATED_P so that GCC is able to
696 generate CFI (Call Frame Information) stuff. */
697 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
699 /* Add CFI info by manual. */
700 REG_NOTES (parallel_insn
) = dwarf
;
703 /* Function to create a parallel rtx pattern
704 which presents stack v3push behavior.
705 The overall concept are:
706 "push registers to memory",
707 "adjust stack pointer". */
709 nds32_emit_stack_v3push (rtx Rb
,
711 rtx En4 ATTRIBUTE_UNUSED
,
725 /* We need to provide a customized rtx which contains
726 necessary information for data analysis,
727 so we create a parallel rtx like this:
728 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
730 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
733 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
735 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
737 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
739 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
741 (set (reg:SI SP_REGNUM)
742 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
744 /* Calculate the number of registers that will be pushed.
745 Since $fp, $gp, and $lp is always pushed with v3push instruction,
746 we need to count these three registers.
747 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
748 So there is no need to worry about Rb=Re=SP_REGNUM case. */
749 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + 3;
751 /* In addition to used registers,
752 we need one more space for (set sp sp-x-imm8u) rtx. */
753 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
754 rtvec_alloc (num_use_regs
+ 1));
757 /* Initialize offset and start to create push behavior. */
758 offset
= -(num_use_regs
* 4);
760 /* Create (set mem regX) from Rb, Rb+1 up to Re.
761 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
762 So there is no need to worry about Rb=Re=SP_REGNUM case. */
763 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
765 reg
= gen_rtx_REG (SImode
, regno
);
766 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
769 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
770 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
771 RTX_FRAME_RELATED_P (push_rtx
) = 1;
776 /* Create (set mem fp). */
777 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
778 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
781 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
782 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
783 RTX_FRAME_RELATED_P (push_rtx
) = 1;
786 /* Create (set mem gp). */
787 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
788 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
791 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
792 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
793 RTX_FRAME_RELATED_P (push_rtx
) = 1;
796 /* Create (set mem lp). */
797 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
798 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
801 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
802 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
803 RTX_FRAME_RELATED_P (push_rtx
) = 1;
807 /* Create (set sp sp-x-imm8u). */
809 /* We need to re-calculate the offset value again for adjustment. */
810 offset
= -(num_use_regs
* 4);
812 = gen_rtx_SET (VOIDmode
,
814 plus_constant (Pmode
,
816 offset
- INTVAL (imm8u
)));
817 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
818 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
820 parallel_insn
= emit_insn (parallel_insn
);
822 /* The insn rtx 'parallel_insn' will change frame layout.
823 We need to use RTX_FRAME_RELATED_P so that GCC is able to
824 generate CFI (Call Frame Information) stuff. */
825 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
828 /* Function to create a parallel rtx pattern
829 which presents stack v3pop behavior.
830 The overall concept are:
831 "pop registers from memory",
832 "adjust stack pointer". */
834 nds32_emit_stack_v3pop (rtx Rb
,
836 rtx En4 ATTRIBUTE_UNUSED
,
849 rtx dwarf
= NULL_RTX
;
851 /* We need to provide a customized rtx which contains
852 necessary information for data analysis,
853 so we create a parallel rtx like this:
854 (parallel [(set (reg:SI Rb)
855 (mem (reg:SI SP_REGNUM)))
857 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
860 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
861 (set (reg:SI FP_REGNUM)
862 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
863 (set (reg:SI GP_REGNUM)
864 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
865 (set (reg:SI LP_REGNUM)
866 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
867 (set (reg:SI SP_REGNUM)
868 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
870 /* Calculate the number of registers that will be poped.
871 Since $fp, $gp, and $lp is always poped with v3pop instruction,
872 we need to count these three registers.
873 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
874 So there is no need to worry about Rb=Re=SP_REGNUM case. */
875 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + 3;
877 /* In addition to used registers,
878 we need one more space for (set sp sp+x+imm8u) rtx. */
879 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
880 rtvec_alloc (num_use_regs
+ 1));
883 /* Initialize offset and start to create pop behavior. */
886 /* Create (set regX mem) from Rb, Rb+1 up to Re.
887 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
888 So there is no need to worry about Rb=Re=SP_REGNUM case. */
889 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
891 reg
= gen_rtx_REG (SImode
, regno
);
892 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
895 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
896 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
897 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
901 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
904 /* Create (set fp mem). */
905 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
906 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
909 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
910 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
911 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
914 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
916 /* Create (set gp mem). */
917 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
918 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
921 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
922 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
923 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
926 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
928 /* Create (set lp mem ). */
929 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
930 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
933 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
934 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
935 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
938 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
940 /* Create (set sp sp+x+imm8u). */
942 /* The offset value is already in place. No need to re-calculate it. */
944 = gen_rtx_SET (VOIDmode
,
946 plus_constant (Pmode
,
948 offset
+ INTVAL (imm8u
)));
949 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
951 /* Tell gcc we adjust SP in this insn. */
952 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
954 parallel_insn
= emit_insn (parallel_insn
);
956 /* The insn rtx 'parallel_insn' will change frame layout.
957 We need to use RTX_FRAME_RELATED_P so that GCC is able to
958 generate CFI (Call Frame Information) stuff. */
959 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
961 /* Add CFI info by manual. */
962 REG_NOTES (parallel_insn
) = dwarf
;
965 /* Function that may creates more instructions
966 for large value on adjusting stack pointer.
968 In nds32 target, 'addi' can be used for stack pointer
969 adjustment in prologue/epilogue stage.
970 However, sometimes there are too many local variables so that
971 the adjustment value is not able to be fit in the 'addi' instruction.
972 One solution is to move value into a register
973 and then use 'add' instruction.
974 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
975 Also, we need to return zero for sp adjustment so that
976 proglogue/epilogue knows there is no need to create 'addi' instruction. */
978 nds32_force_addi_stack_int (int full_value
)
985 if (!satisfies_constraint_Is15 (GEN_INT (full_value
)))
987 /* The value is not able to fit in single addi instruction.
988 Create more instructions of moving value into a register
989 and then add stack pointer with it. */
991 /* $r15 is going to be temporary register to hold the value. */
992 tmp_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
994 /* Create one more instruction to move value
995 into the temporary register. */
996 emit_move_insn (tmp_reg
, GEN_INT (full_value
));
998 /* Create new 'add' rtx. */
999 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
1002 /* Emit rtx into insn list and receive its transformed insn rtx. */
1003 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
1005 /* At prologue, we need to tell GCC that this is frame related insn,
1006 so that we can consider this instruction to output debug information.
1007 If full_value is NEGATIVE, it means this function
1008 is invoked by expand_prologue. */
1011 /* Because (tmp_reg <- full_value) may be split into two
1012 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1013 We need to construct another (sp <- sp + full_value)
1014 and then insert it into sp_adjust_insn's reg note to
1015 represent a frame related expression.
1016 GCC knows how to refer it and output debug information. */
1021 plus_rtx
= plus_constant (Pmode
, stack_pointer_rtx
, full_value
);
1022 set_rtx
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
, plus_rtx
);
1023 add_reg_note (sp_adjust_insn
, REG_FRAME_RELATED_EXPR
, set_rtx
);
1025 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
1028 /* We have used alternative way to adjust stack pointer value.
1029 Return zero so that prologue/epilogue
1030 will not generate other instructions. */
1035 /* The value is able to fit in addi instruction.
1036 However, remember to make it to be positive value
1037 because we want to return 'adjustment' result. */
1038 adjust_value
= (full_value
< 0) ? (-full_value
) : (full_value
);
1040 return adjust_value
;
1044 /* Return true if MODE/TYPE need double word alignment. */
1046 nds32_needs_double_word_align (machine_mode mode
, const_tree type
)
1050 /* Pick up the alignment according to the mode or type. */
1051 align
= NDS32_MODE_TYPE_ALIGN (mode
, type
);
1053 return (align
> PARM_BOUNDARY
);
1056 /* Return true if FUNC is a naked function. */
1058 nds32_naked_function_p (tree func
)
1062 if (TREE_CODE (func
) != FUNCTION_DECL
)
1065 t
= lookup_attribute ("naked", DECL_ATTRIBUTES (func
));
1067 return (t
!= NULL_TREE
);
1070 /* Function that check if 'X' is a valid address register.
1071 The variable 'STRICT' is very important to
1072 make decision for register number.
1075 => We are in reload pass or after reload pass.
1076 The register number should be strictly limited in general registers.
1079 => Before reload pass, we are free to use any register number. */
1081 nds32_address_register_rtx_p (rtx x
, bool strict
)
1085 if (GET_CODE (x
) != REG
)
1091 return REGNO_OK_FOR_BASE_P (regno
);
1096 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1098 OUTER_MODE : Machine mode of outer address rtx.
1099 INDEX : Check if this rtx is valid to be a index for address.
1100 STRICT : If it is true, we are in reload pass or after reload pass. */
1102 nds32_legitimate_index_p (machine_mode outer_mode
,
1110 switch (GET_CODE (index
))
1113 regno
= REGNO (index
);
1114 /* If we are in reload pass or after reload pass,
1115 we need to limit it to general register. */
1117 return REGNO_OK_FOR_INDEX_P (regno
);
1122 /* The alignment of the integer value is determined by 'outer_mode'. */
1123 if (GET_MODE_SIZE (outer_mode
) == 1)
1125 /* Further check if the value is legal for the 'outer_mode'. */
1126 if (!satisfies_constraint_Is15 (index
))
1129 /* Pass all test, the value is valid, return true. */
1132 if (GET_MODE_SIZE (outer_mode
) == 2
1133 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index
)))
1135 /* Further check if the value is legal for the 'outer_mode'. */
1136 if (!satisfies_constraint_Is16 (index
))
1139 /* Pass all test, the value is valid, return true. */
1142 if (GET_MODE_SIZE (outer_mode
) == 4
1143 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1145 /* Further check if the value is legal for the 'outer_mode'. */
1146 if (!satisfies_constraint_Is17 (index
))
1149 /* Pass all test, the value is valid, return true. */
1152 if (GET_MODE_SIZE (outer_mode
) == 8
1153 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1155 /* Further check if the value is legal for the 'outer_mode'. */
1156 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index
) + 4,
1160 /* Pass all test, the value is valid, return true. */
1167 op0
= XEXP (index
, 0);
1168 op1
= XEXP (index
, 1);
1170 if (REG_P (op0
) && CONST_INT_P (op1
))
1173 multiplier
= INTVAL (op1
);
1175 /* We only allow (mult reg const_int_1)
1176 or (mult reg const_int_2) or (mult reg const_int_4). */
1177 if (multiplier
!= 1 && multiplier
!= 2 && multiplier
!= 4)
1180 regno
= REGNO (op0
);
1181 /* Limit it in general registers if we are
1182 in reload pass or after reload pass. */
1184 return REGNO_OK_FOR_INDEX_P (regno
);
1192 op0
= XEXP (index
, 0);
1193 op1
= XEXP (index
, 1);
1195 if (REG_P (op0
) && CONST_INT_P (op1
))
1198 /* op1 is already the sv value for use to do left shift. */
1201 /* We only allow (ashift reg const_int_0)
1202 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1203 if (sv
!= 0 && sv
!= 1 && sv
!=2)
1206 regno
= REGNO (op0
);
1207 /* Limit it in general registers if we are
1208 in reload pass or after reload pass. */
1210 return REGNO_OK_FOR_INDEX_P (regno
);
1222 /* ------------------------------------------------------------------------ */
1224 /* PART 3: Implement target hook stuff definitions. */
1226 /* Register Classes. */
1228 static unsigned char
1229 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED
,
1232 /* Return the maximum number of consecutive registers
1233 needed to represent "mode" in a register of "rclass". */
1234 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
1238 nds32_register_priority (int hard_regno
)
1240 /* Encourage to use r0-r7 for LRA when optimize for size. */
1241 if (optimize_size
&& hard_regno
< 8)
1247 /* Stack Layout and Calling Conventions. */
1249 /* There are three kinds of pointer concepts using in GCC compiler:
1251 frame pointer: A pointer to the first location of local variables.
1252 stack pointer: A pointer to the top of a stack frame.
1253 argument pointer: A pointer to the incoming arguments.
1255 In nds32 target calling convention, we are using 8-byte alignment.
1256 Besides, we would like to have each stack frame of a function includes:
1259 1. previous hard frame pointer
1261 3. callee-saved registers
1262 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1264 cfun->machine->callee_saved_area_padding_bytes)
1268 2. spilling location
1269 3. <padding bytes> (it will be calculated by GCC itself)
1270 4. incoming arguments
1271 5. <padding bytes> (it will be calculated by GCC itself)
1274 1. <padding bytes> (it will be calculated by GCC itself)
1275 2. outgoing arguments
1277 We 'wrap' these blocks together with
1278 hard frame pointer ($r28) and stack pointer ($r31).
1279 By applying the basic frame/stack/argument pointers concept,
1280 the layout of a stack frame shoule be like this:
1283 old stack pointer -> ----
1285 | | saved arguments for
1286 | | vararg functions
1288 hard frame pointer -> --
1289 & argument pointer | | \
1290 | | previous hardware frame pointer
1292 | | callee-saved registers
1297 | | and incoming arguments
1304 stack pointer -> ----
1306 $SFP and $AP are used to represent frame pointer and arguments pointer,
1307 which will be both eliminated as hard frame pointer. */
1309 /* -- Eliminating Frame Pointer and Arg Pointer. */
1312 nds32_can_eliminate (const int from_reg
, const int to_reg
)
1314 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1317 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1320 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1323 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1329 /* -- Passing Arguments in Registers. */
1332 nds32_function_arg (cumulative_args_t ca
, machine_mode mode
,
1333 const_tree type
, bool named
)
1336 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1338 /* The last time this hook is called,
1339 it is called with MODE == VOIDmode. */
1340 if (mode
== VOIDmode
)
1343 /* For nameless arguments, we need to take care it individually. */
1346 /* If we are under hard float abi, we have arguments passed on the
1347 stack and all situation can be handled by GCC itself. */
1348 if (TARGET_HARD_FLOAT
)
1351 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1353 /* If we still have enough registers to pass argument, pick up
1354 next available register number. */
1356 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1357 return gen_rtx_REG (mode
, regno
);
1360 /* No register available, return NULL_RTX.
1361 The compiler will use stack to pass argument instead. */
1365 /* The following is to handle named argument.
1366 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1368 if (TARGET_HARD_FLOAT
)
1370 /* Currently we have not implemented hard float yet. */
1375 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1376 argument. Since we allow to pass argument partially in registers,
1377 we can just return it if there are still registers available. */
1378 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1380 /* Pick up the next available register number. */
1382 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1383 return gen_rtx_REG (mode
, regno
);
1388 /* No register available, return NULL_RTX.
1389 The compiler will use stack to pass argument instead. */
1394 nds32_must_pass_in_stack (machine_mode mode
, const_tree type
)
1396 /* Return true if a type must be passed in memory.
1397 If it is NOT using hard float abi, small aggregates can be
1398 passed in a register even we are calling a variadic function.
1399 So there is no need to take padding into consideration. */
1400 if (TARGET_HARD_FLOAT
)
1401 return must_pass_in_stack_var_size_or_pad (mode
, type
);
1403 return must_pass_in_stack_var_size (mode
, type
);
1407 nds32_arg_partial_bytes (cumulative_args_t ca
, machine_mode mode
,
1408 tree type
, bool named ATTRIBUTE_UNUSED
)
1410 /* Returns the number of bytes at the beginning of an argument that
1411 must be put in registers. The value must be zero for arguments that are
1412 passed entirely in registers or that are entirely pushed on the stack.
1413 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1414 first register to be used by the caller for this argument. */
1415 unsigned int needed_reg_count
;
1416 unsigned int remaining_reg_count
;
1417 CUMULATIVE_ARGS
*cum
;
1419 cum
= get_cumulative_args (ca
);
1421 /* Under hard float abi, we better have argument entirely passed in
1422 registers or pushed on the stack so that we can reduce the complexity
1423 of dealing with cum->gpr_offset and cum->fpr_offset. */
1424 if (TARGET_HARD_FLOAT
)
1427 /* If we have already runned out of argument registers, return zero
1428 so that the argument will be entirely pushed on the stack. */
1429 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1430 >= NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
)
1433 /* Calculate how many registers do we need for this argument. */
1434 needed_reg_count
= NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1436 /* Calculate how many argument registers have left for passing argument.
1437 Note that we should count it from next available register number. */
1439 = NDS32_MAX_GPR_REGS_FOR_ARGS
1440 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1441 - NDS32_GPR_ARG_FIRST_REGNUM
);
1443 /* Note that we have to return the nubmer of bytes, not registers count. */
1444 if (needed_reg_count
> remaining_reg_count
)
1445 return remaining_reg_count
* UNITS_PER_WORD
;
1451 nds32_function_arg_advance (cumulative_args_t ca
, machine_mode mode
,
1452 const_tree type
, bool named
)
1454 machine_mode sub_mode
;
1455 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1459 /* We need to further check TYPE and MODE so that we can determine
1460 which kind of register we shall advance. */
1461 if (type
&& TREE_CODE (type
) == COMPLEX_TYPE
)
1462 sub_mode
= TYPE_MODE (TREE_TYPE (type
));
1466 /* Under hard float abi, we may advance FPR registers. */
1467 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (sub_mode
) == MODE_FLOAT
)
1469 /* Currently we have not implemented hard float yet. */
1475 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1476 - NDS32_GPR_ARG_FIRST_REGNUM
1477 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1482 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1483 we can advance next register as well so that caller is
1484 able to pass arguments in registers and callee must be
1485 in charge of pushing all of them into stack. */
1486 if (!TARGET_HARD_FLOAT
)
1489 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1490 - NDS32_GPR_ARG_FIRST_REGNUM
1491 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1497 nds32_function_arg_boundary (machine_mode mode
, const_tree type
)
1499 return (nds32_needs_double_word_align (mode
, type
)
1500 ? NDS32_DOUBLE_WORD_ALIGNMENT
1504 /* -- How Scalar Function Values Are Returned. */
1507 nds32_function_value (const_tree ret_type
,
1508 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1509 bool outgoing ATTRIBUTE_UNUSED
)
1514 mode
= TYPE_MODE (ret_type
);
1515 unsignedp
= TYPE_UNSIGNED (ret_type
);
1517 mode
= promote_mode (ret_type
, mode
, &unsignedp
);
1519 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
1523 nds32_libcall_value (machine_mode mode
,
1524 const_rtx fun ATTRIBUTE_UNUSED
)
1526 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
1530 nds32_function_value_regno_p (const unsigned int regno
)
1532 return (regno
== NDS32_GPR_RET_FIRST_REGNUM
);
1535 /* -- Function Entry and Exit. */
1537 /* The content produced from this function
1538 will be placed before prologue body. */
1540 nds32_asm_function_prologue (FILE *file
,
1541 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1544 const char *func_name
;
1548 /* All stack frame information is supposed to be
1549 already computed when expanding prologue.
1550 The result is in cfun->machine.
1551 DO NOT call nds32_compute_stack_frame() here
1552 because it may corrupt the essential information. */
1554 fprintf (file
, "\t! BEGIN PROLOGUE\n");
1555 fprintf (file
, "\t! fp needed: %d\n", frame_pointer_needed
);
1556 fprintf (file
, "\t! pretend_args: %d\n", cfun
->machine
->va_args_size
);
1557 fprintf (file
, "\t! local_size: %d\n", cfun
->machine
->local_size
);
1558 fprintf (file
, "\t! out_args_size: %d\n", cfun
->machine
->out_args_size
);
1560 /* Use df_regs_ever_live_p() to detect if the register
1561 is ever used in the current function. */
1562 fprintf (file
, "\t! registers ever_live: ");
1563 for (r
= 0; r
< 32; r
++)
1565 if (df_regs_ever_live_p (r
))
1566 fprintf (file
, "%s, ", reg_names
[r
]);
1570 /* Display the attributes of this function. */
1571 fprintf (file
, "\t! function attributes: ");
1572 /* Get the attributes tree list.
1573 Note that GCC builds attributes list with reverse order. */
1574 attrs
= DECL_ATTRIBUTES (current_function_decl
);
1576 /* If there is no any attribute, print out "None". */
1578 fprintf (file
, "None");
1580 /* If there are some attributes, try if we need to
1581 construct isr vector information. */
1582 func_name
= IDENTIFIER_POINTER (DECL_NAME (current_function_decl
));
1583 nds32_construct_isr_vectors_information (attrs
, func_name
);
1585 /* Display all attributes of this function. */
1588 name
= TREE_PURPOSE (attrs
);
1589 fprintf (file
, "%s ", IDENTIFIER_POINTER (name
));
1591 /* Pick up the next attribute. */
1592 attrs
= TREE_CHAIN (attrs
);
1597 /* After rtl prologue has been expanded, this function is used. */
1599 nds32_asm_function_end_prologue (FILE *file
)
1601 fprintf (file
, "\t! END PROLOGUE\n");
1603 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1604 we can generate special directive: ".omit_fp_begin"
1605 to guide linker doing fp-as-gp optimization.
1606 However, for a naked function, which means
1607 it should not have prologue/epilogue,
1608 using fp-as-gp still requires saving $fp by push/pop behavior and
1609 there is no benefit to use fp-as-gp on such small function.
1610 So we need to make sure this function is NOT naked as well. */
1611 if (!frame_pointer_needed
1612 && !cfun
->machine
->naked_p
1613 && cfun
->machine
->fp_as_gp_p
)
1615 fprintf (file
, "\t! ----------------------------------------\n");
1616 fprintf (file
, "\t! Guide linker to do "
1617 "link time optimization: fp-as-gp\n");
1618 fprintf (file
, "\t! We add one more instruction to "
1619 "initialize $fp near to $gp location.\n");
1620 fprintf (file
, "\t! If linker fails to use fp-as-gp transformation,\n");
1621 fprintf (file
, "\t! this extra instruction should be "
1622 "eliminated at link stage.\n");
1623 fprintf (file
, "\t.omit_fp_begin\n");
1624 fprintf (file
, "\tla\t$fp,_FP_BASE_\n");
1625 fprintf (file
, "\t! ----------------------------------------\n");
1629 /* Before rtl epilogue has been expanded, this function is used. */
1631 nds32_asm_function_begin_epilogue (FILE *file
)
1633 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1634 we can generate special directive: ".omit_fp_end"
1635 to claim fp-as-gp optimization range.
1636 However, for a naked function,
1637 which means it should not have prologue/epilogue,
1638 using fp-as-gp still requires saving $fp by push/pop behavior and
1639 there is no benefit to use fp-as-gp on such small function.
1640 So we need to make sure this function is NOT naked as well. */
1641 if (!frame_pointer_needed
1642 && !cfun
->machine
->naked_p
1643 && cfun
->machine
->fp_as_gp_p
)
1645 fprintf (file
, "\t! ----------------------------------------\n");
1646 fprintf (file
, "\t! Claim the range of fp-as-gp "
1647 "link time optimization\n");
1648 fprintf (file
, "\t.omit_fp_end\n");
1649 fprintf (file
, "\t! ----------------------------------------\n");
1652 fprintf (file
, "\t! BEGIN EPILOGUE\n");
1655 /* The content produced from this function
1656 will be placed after epilogue body. */
1658 nds32_asm_function_epilogue (FILE *file
,
1659 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1661 fprintf (file
, "\t! END EPILOGUE\n");
1665 nds32_asm_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
1666 HOST_WIDE_INT delta
,
1667 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
1672 /* Make sure unwind info is emitted for the thunk if needed. */
1673 final_start_function (emit_barrier (), file
, 1);
1675 this_regno
= (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
)
1681 if (satisfies_constraint_Is15 (GEN_INT (delta
)))
1683 fprintf (file
, "\taddi\t$r%d, $r%d, %ld\n",
1684 this_regno
, this_regno
, delta
);
1686 else if (satisfies_constraint_Is20 (GEN_INT (delta
)))
1688 fprintf (file
, "\tmovi\t$ta, %ld\n", delta
);
1689 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
1693 fprintf (file
, "\tsethi\t$ta, hi20(%ld)\n", delta
);
1694 fprintf (file
, "\tori\t$ta, $ta, lo12(%ld)\n", delta
);
1695 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
1699 fprintf (file
, "\tb\t");
1700 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
1701 fprintf (file
, "\n");
1703 final_end_function ();
1706 /* -- Permitting tail calls. */
1708 /* Determine whether we need to enable warning for function return check. */
1710 nds32_warn_func_return (tree decl
)
1712 /* Naked functions are implemented entirely in assembly, including the
1713 return sequence, so suppress warnings about this. */
1714 return !nds32_naked_function_p (decl
);
1718 /* Implementing the Varargs Macros. */
1721 nds32_setup_incoming_varargs (cumulative_args_t ca
,
1724 int *pretend_args_size
,
1725 int second_time ATTRIBUTE_UNUSED
)
1727 unsigned int total_args_regs
;
1728 unsigned int num_of_used_regs
;
1729 unsigned int remaining_reg_count
;
1730 CUMULATIVE_ARGS
*cum
;
1732 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1733 So that all nameless arguments are pushed by caller and all situation
1734 can be handled by GCC itself. */
1735 if (TARGET_HARD_FLOAT
)
1738 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1739 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1740 However, for nameless(anonymous) arguments, we should push them on the
1741 stack so that all the nameless arguments appear to have been passed
1742 consecutively in the memory for accessing. Hence, we need to check and
1743 exclude the registers that are used for named arguments. */
1745 cum
= get_cumulative_args (ca
);
1747 /* The MODE and TYPE describe the last argument.
1748 We need those information to determine the remaining registers
1751 = NDS32_MAX_GPR_REGS_FOR_ARGS
+ NDS32_GPR_ARG_FIRST_REGNUM
;
1753 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1754 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1756 remaining_reg_count
= total_args_regs
- num_of_used_regs
;
1757 *pretend_args_size
= remaining_reg_count
* UNITS_PER_WORD
;
1763 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
1765 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1766 true for named arguments, and false for unnamed arguments. */
1771 /* Trampolines for Nested Functions. */
1774 nds32_asm_trampoline_template (FILE *f
)
1776 if (TARGET_REDUCED_REGS
)
1778 /* Trampoline is not supported on reduced-set registers yet. */
1779 sorry ("a nested function is not supported for reduced registers");
1783 asm_fprintf (f
, "\t! Trampoline code template\n");
1784 asm_fprintf (f
, "\t! This code fragment will be copied "
1785 "into stack on demand\n");
1787 asm_fprintf (f
, "\tmfusr\t$r16,$pc\n");
1788 asm_fprintf (f
, "\tlwi\t$r15,[$r16 + 20] "
1789 "! load nested function address\n");
1790 asm_fprintf (f
, "\tlwi\t$r16,[$r16 + 16] "
1791 "! load chain_value\n");
1792 asm_fprintf (f
, "\tjr\t$r15\n");
1795 /* Preserve space ($pc + 16) for saving chain_value,
1796 nds32_trampoline_init will fill the value in this slot. */
1797 asm_fprintf (f
, "\t! space for saving chain_value\n");
1798 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
1800 /* Preserve space ($pc + 20) for saving nested function address,
1801 nds32_trampoline_init will fill the value in this slot. */
1802 asm_fprintf (f
, "\t! space for saving nested function address\n");
1803 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
1806 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1808 nds32_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
1812 /* Nested function address. */
1814 /* The memory rtx that is going to
1815 be filled with chain_value. */
1816 rtx chain_value_mem
;
1817 /* The memory rtx that is going to
1818 be filled with nested function address. */
1819 rtx nested_func_mem
;
1821 /* Start address of trampoline code in stack, for doing cache sync. */
1822 rtx sync_cache_addr
;
1823 /* Temporary register for sync instruction. */
1825 /* Instruction-cache sync instruction,
1826 requesting an argument as starting address. */
1828 /* For convenience reason of doing comparison. */
1829 int tramp_align_in_bytes
;
1831 /* Trampoline is not supported on reduced-set registers yet. */
1832 if (TARGET_REDUCED_REGS
)
1833 sorry ("a nested function is not supported for reduced registers");
1835 /* STEP 1: Copy trampoline code template into stack,
1836 fill up essential data into stack. */
1838 /* Extract nested function address rtx. */
1839 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
1841 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1842 We have nds32_asm_trampoline_template() to emit template pattern. */
1843 emit_block_move (m_tramp
, assemble_trampoline_template (),
1844 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
1846 /* After copying trampoline code into stack,
1847 fill chain_value into stack. */
1848 chain_value_mem
= adjust_address (m_tramp
, SImode
, 16);
1849 emit_move_insn (chain_value_mem
, chain_value
);
1850 /* After copying trampoline code int stack,
1851 fill nested function address into stack. */
1852 nested_func_mem
= adjust_address (m_tramp
, SImode
, 20);
1853 emit_move_insn (nested_func_mem
, fnaddr
);
1855 /* STEP 2: Sync instruction-cache. */
1857 /* We have successfully filled trampoline code into stack.
1858 However, in order to execute code in stack correctly,
1859 we must sync instruction cache. */
1860 sync_cache_addr
= XEXP (m_tramp
, 0);
1861 tmp_reg
= gen_reg_rtx (SImode
);
1862 isync_insn
= gen_unspec_volatile_isync (tmp_reg
);
1864 /* Because nds32_cache_block_size is in bytes,
1865 we get trampoline alignment in bytes for convenient comparison. */
1866 tramp_align_in_bytes
= TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
;
1868 if (tramp_align_in_bytes
>= nds32_cache_block_size
1869 && (tramp_align_in_bytes
% nds32_cache_block_size
) == 0)
1871 /* Under this condition, the starting address of trampoline
1872 must be aligned to the starting address of each cache block
1873 and we do not have to worry about cross-boundary issue. */
1875 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
1876 / nds32_cache_block_size
;
1879 emit_move_insn (tmp_reg
,
1880 plus_constant (Pmode
, sync_cache_addr
,
1881 nds32_cache_block_size
* i
));
1882 emit_insn (isync_insn
);
1885 else if (TRAMPOLINE_SIZE
> nds32_cache_block_size
)
1887 /* The starting address of trampoline code
1888 may not be aligned to the cache block,
1889 so the trampoline code may be across two cache block.
1890 We need to sync the last element, which is 4-byte size,
1891 of trampoline template. */
1893 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
1894 / nds32_cache_block_size
;
1897 emit_move_insn (tmp_reg
,
1898 plus_constant (Pmode
, sync_cache_addr
,
1899 nds32_cache_block_size
* i
));
1900 emit_insn (isync_insn
);
1903 /* The last element of trampoline template is 4-byte size. */
1904 emit_move_insn (tmp_reg
,
1905 plus_constant (Pmode
, sync_cache_addr
,
1906 TRAMPOLINE_SIZE
- 4));
1907 emit_insn (isync_insn
);
1911 /* This is the simplest case.
1912 Because TRAMPOLINE_SIZE is less than or
1913 equal to nds32_cache_block_size,
1914 we can just sync start address and
1915 the last element of trampoline code. */
1917 /* Sync starting address of tampoline code. */
1918 emit_move_insn (tmp_reg
, sync_cache_addr
);
1919 emit_insn (isync_insn
);
1920 /* Sync the last element, which is 4-byte size,
1921 of trampoline template. */
1922 emit_move_insn (tmp_reg
,
1923 plus_constant (Pmode
, sync_cache_addr
,
1924 TRAMPOLINE_SIZE
- 4));
1925 emit_insn (isync_insn
);
1928 /* Set instruction serialization barrier
1929 to guarantee the correct operations. */
1930 emit_insn (gen_unspec_volatile_isb ());
1934 /* Addressing Modes. */
1937 nds32_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
1939 /* For (mem:DI addr) or (mem:DF addr) case,
1940 we only allow 'addr' to be [reg], [symbol_ref],
1941 [const], or [reg + const_int] pattern. */
1942 if (mode
== DImode
|| mode
== DFmode
)
1944 /* Allow [Reg + const_int] addressing mode. */
1945 if (GET_CODE (x
) == PLUS
)
1947 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
1948 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
)
1949 && CONST_INT_P (XEXP (x
, 1)))
1952 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
1953 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
)
1954 && CONST_INT_P (XEXP (x
, 0)))
1958 /* Now check [reg], [symbol_ref], and [const]. */
1959 if (GET_CODE (x
) != REG
1960 && GET_CODE (x
) != SYMBOL_REF
1961 && GET_CODE (x
) != CONST
)
1965 /* Check if 'x' is a valid address. */
1966 switch (GET_CODE (x
))
1969 /* (mem (reg A)) => [Ra] */
1970 return nds32_address_register_rtx_p (x
, strict
);
1973 /* (mem (symbol_ref A)) => [symbol_ref] */
1974 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
1975 during or after LRA/reload phase. */
1976 if (TARGET_CMODEL_LARGE
1977 && (reload_completed
1978 || reload_in_progress
1979 || lra_in_progress
))
1981 /* If -mcmodel=medium and the symbol references to rodata section,
1982 the 'symbol_ref' is not a valid address during or after
1983 LRA/reload phase. */
1984 if (TARGET_CMODEL_MEDIUM
1985 && NDS32_SYMBOL_REF_RODATA_P (x
)
1986 && (reload_completed
1987 || reload_in_progress
1988 || lra_in_progress
))
1994 /* (mem (const (...)))
1995 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1996 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
1998 rtx plus_op
= XEXP (x
, 0);
2000 rtx op0
= XEXP (plus_op
, 0);
2001 rtx op1
= XEXP (plus_op
, 1);
2003 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2005 /* Now we see the [ + const_addr ] pattern, but we need
2006 some further checking. */
2007 /* If -mcmodel=large, the 'const_addr' is not a valid address
2008 during or after LRA/reload phase. */
2009 if (TARGET_CMODEL_LARGE
2010 && (reload_completed
2011 || reload_in_progress
2012 || lra_in_progress
))
2014 /* If -mcmodel=medium and the symbol references to rodata section,
2015 the 'const_addr' is not a valid address during or after
2016 LRA/reload phase. */
2017 if (TARGET_CMODEL_MEDIUM
2018 && NDS32_SYMBOL_REF_RODATA_P (op0
)
2019 && (reload_completed
2020 || reload_in_progress
2021 || lra_in_progress
))
2024 /* At this point we can make sure 'const_addr' is a
2033 /* (mem (post_modify (reg) (plus (reg) (reg))))
2035 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2036 => [Ra], const_int */
2037 if (GET_CODE (XEXP (x
, 0)) == REG
2038 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2040 rtx plus_op
= XEXP (x
, 1);
2042 rtx op0
= XEXP (plus_op
, 0);
2043 rtx op1
= XEXP (plus_op
, 1);
2045 if (nds32_address_register_rtx_p (op0
, strict
)
2046 && nds32_legitimate_index_p (mode
, op1
, strict
))
2056 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2057 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2058 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2059 We only need to deal with register Ra. */
2060 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2066 /* (mem (plus reg const_int))
2068 /* (mem (plus reg reg))
2070 /* (mem (plus (mult reg const_int) reg))
2071 => [Ra + Rb << sv] */
2072 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2073 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
))
2075 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2076 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
))
2082 /* (mem (lo_sum (reg) (symbol_ref))) */
2083 /* (mem (lo_sum (reg) (const))) */
2084 gcc_assert (REG_P (XEXP (x
, 0)));
2085 if (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
2086 || GET_CODE (XEXP (x
, 1)) == CONST
)
2087 return nds32_legitimate_address_p (mode
, XEXP (x
, 1), strict
);
2097 /* Describing Relative Costs of Operations. */
2100 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2104 if (from
== HIGH_REGS
|| to
== HIGH_REGS
)
2111 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2112 reg_class_t rclass ATTRIBUTE_UNUSED
,
2113 bool in ATTRIBUTE_UNUSED
)
2118 /* This target hook describes the relative costs of RTL expressions.
2119 Return 'true' when all subexpressions of x have been processed.
2120 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2121 Refer to gcc/rtlanal.c for more information. */
2123 nds32_rtx_costs (rtx x
,
2130 return nds32_rtx_costs_impl (x
, code
, outer_code
, opno
, total
, speed
);
2134 nds32_address_cost (rtx address
,
2139 return nds32_address_cost_impl (address
, mode
, as
, speed
);
2143 /* Dividing the Output into Sections (Texts, Data, . . . ). */
2145 /* If references to a symbol or a constant must be treated differently
2146 depending on something about the variable or function named by the symbol
2147 (such as what section it is in), we use this hook to store flags
2148 in symbol_ref rtx. */
2150 nds32_encode_section_info (tree decl
, rtx rtl
, int new_decl_p
)
2152 default_encode_section_info (decl
, rtl
, new_decl_p
);
2154 /* For the memory rtx, if it references to rodata section, we can store
2155 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
2156 nds32_legitimate_address_p() can determine how to treat such symbol_ref
2157 based on -mcmodel=X and this information. */
2158 if (MEM_P (rtl
) && MEM_READONLY_P (rtl
))
2160 rtx addr
= XEXP (rtl
, 0);
2162 if (GET_CODE (addr
) == SYMBOL_REF
)
2164 /* For (mem (symbol_ref X)) case. */
2165 SYMBOL_REF_FLAGS (addr
) |= NDS32_SYMBOL_FLAG_RODATA
;
2167 else if (GET_CODE (addr
) == CONST
2168 && GET_CODE (XEXP (addr
, 0)) == PLUS
)
2170 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
2171 rtx plus_op
= XEXP (addr
, 0);
2172 rtx op0
= XEXP (plus_op
, 0);
2173 rtx op1
= XEXP (plus_op
, 1);
2175 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2176 SYMBOL_REF_FLAGS (op0
) |= NDS32_SYMBOL_FLAG_RODATA
;
2182 /* Defining the Output Assembler Language. */
2184 /* -- The Overall Framework of an Assembler File. */
2187 nds32_asm_file_start (void)
2189 default_file_start ();
2191 /* Tell assembler which ABI we are using. */
2192 fprintf (asm_out_file
, "\t! ABI version\n");
2193 fprintf (asm_out_file
, "\t.abi_2\n");
2195 /* Tell assembler that this asm code is generated by compiler. */
2196 fprintf (asm_out_file
, "\t! This asm file is generated by compiler\n");
2197 fprintf (asm_out_file
, "\t.flag\tverbatim\n");
2198 /* Give assembler the size of each vector for interrupt handler. */
2199 fprintf (asm_out_file
, "\t! This vector size directive is required "
2200 "for checking inconsistency on interrupt handler\n");
2201 fprintf (asm_out_file
, "\t.vec_size\t%d\n", nds32_isr_vector_size
);
2203 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2206 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V2");
2208 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3");
2210 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3M");
2212 if (TARGET_CMODEL_SMALL
)
2213 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "SMALL");
2214 if (TARGET_CMODEL_MEDIUM
)
2215 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "MEDIUM");
2216 if (TARGET_CMODEL_LARGE
)
2217 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "LARGE");
2219 fprintf (asm_out_file
, "\t! Endian setting\t: %s\n",
2220 ((TARGET_BIG_ENDIAN
) ? "big-endian"
2221 : "little-endian"));
2223 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2225 fprintf (asm_out_file
, "\t! Use conditional move\t\t: %s\n",
2226 ((TARGET_CMOV
) ? "Yes"
2228 fprintf (asm_out_file
, "\t! Use performance extension\t: %s\n",
2229 ((TARGET_PERF_EXT
) ? "Yes"
2232 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2234 fprintf (asm_out_file
, "\t! V3PUSH instructions\t: %s\n",
2235 ((TARGET_V3PUSH
) ? "Yes"
2237 fprintf (asm_out_file
, "\t! 16-bit instructions\t: %s\n",
2238 ((TARGET_16_BIT
) ? "Yes"
2240 fprintf (asm_out_file
, "\t! Reduced registers set\t: %s\n",
2241 ((TARGET_REDUCED_REGS
) ? "Yes"
2244 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2247 fprintf (asm_out_file
, "\t! Optimization level\t: -Os\n");
2249 fprintf (asm_out_file
, "\t! Optimization level\t: -O%d\n", optimize
);
2251 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2253 fprintf (asm_out_file
, "\t! Cache block size\t: %d\n",
2254 nds32_cache_block_size
);
2256 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2258 nds32_asm_file_start_for_isr ();
2262 nds32_asm_file_end (void)
2264 nds32_asm_file_end_for_isr ();
2266 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2269 /* -- Output and Generation of Labels. */
2272 nds32_asm_globalize_label (FILE *stream
, const char *name
)
2274 fputs ("\t.global\t", stream
);
2275 assemble_name (stream
, name
);
2276 fputs ("\n", stream
);
2279 /* -- Output of Assembler Instructions. */
2282 nds32_print_operand (FILE *stream
, rtx x
, int code
)
2289 /* Do nothing special. */
2293 /* 'x' is supposed to be CONST_INT, get the value. */
2294 gcc_assert (CONST_INT_P (x
));
2295 op_value
= INTVAL (x
);
2297 /* According to the Andes architecture,
2298 the system/user register index range is 0 ~ 1023.
2299 In order to avoid conflict between user-specified-integer value
2300 and enum-specified-register value,
2301 the 'enum nds32_intrinsic_registers' value
2302 in nds32_intrinsic.h starts from 1024. */
2303 if (op_value
< 1024 && op_value
>= 0)
2305 /* If user gives integer value directly (0~1023),
2306 we just print out the value. */
2307 fprintf (stream
, "%d", op_value
);
2309 else if (op_value
< 0
2310 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
2313 /* The enum index value for array size is out of range. */
2314 error ("intrinsic register index is out of range");
2318 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2319 we can print out register name. Remember to substract 1024. */
2320 fprintf (stream
, "%s",
2321 nds32_intrinsic_register_names
[op_value
- 1024]);
2324 /* No need to handle following process, so return immediately. */
2329 output_operand_lossage ("invalid operand output code");
2333 switch (GET_CODE (x
))
2337 output_addr_const (stream
, x
);
2341 /* Forbid using static chain register ($r16)
2342 on reduced-set registers configuration. */
2343 if (TARGET_REDUCED_REGS
2344 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
2345 sorry ("a nested function is not supported for reduced registers");
2347 /* Normal cases, print out register name. */
2348 fputs (reg_names
[REGNO (x
)], stream
);
2352 output_address (XEXP (x
, 0));
2358 output_addr_const (stream
, x
);
2362 /* Generally, output_addr_const () is able to handle most cases.
2363 We want to see what CODE could appear,
2364 so we use gcc_unreachable() to stop it. */
2372 nds32_print_operand_address (FILE *stream
, rtx x
)
2376 switch (GET_CODE (x
))
2380 /* [ + symbol_ref] */
2381 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2382 fputs ("[ + ", stream
);
2383 output_addr_const (stream
, x
);
2384 fputs ("]", stream
);
2388 /* Forbid using static chain register ($r16)
2389 on reduced-set registers configuration. */
2390 if (TARGET_REDUCED_REGS
2391 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
2392 sorry ("a nested function is not supported for reduced registers");
2395 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
2402 /* Checking op0, forbid using static chain register ($r16)
2403 on reduced-set registers configuration. */
2404 if (TARGET_REDUCED_REGS
2406 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2407 sorry ("a nested function is not supported for reduced registers");
2408 /* Checking op1, forbid using static chain register ($r16)
2409 on reduced-set registers configuration. */
2410 if (TARGET_REDUCED_REGS
2412 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
2413 sorry ("a nested function is not supported for reduced registers");
2415 if (REG_P (op0
) && CONST_INT_P (op1
))
2418 fprintf (stream
, "[%s + (%d)]",
2419 reg_names
[REGNO (op0
)], (int)INTVAL (op1
));
2421 else if (REG_P (op0
) && REG_P (op1
))
2424 fprintf (stream
, "[%s + %s]",
2425 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
2427 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
2430 From observation, the pattern looks like:
2431 (plus:SI (mult:SI (reg:SI 58)
2432 (const_int 4 [0x4]))
2436 /* We need to set sv to output shift value. */
2437 if (INTVAL (XEXP (op0
, 1)) == 1)
2439 else if (INTVAL (XEXP (op0
, 1)) == 2)
2441 else if (INTVAL (XEXP (op0
, 1)) == 4)
2446 fprintf (stream
, "[%s + %s << %d]",
2447 reg_names
[REGNO (op1
)],
2448 reg_names
[REGNO (XEXP (op0
, 0))],
2453 /* The control flow is not supposed to be here. */
2461 /* (post_modify (regA) (plus (regA) (regB)))
2462 (post_modify (regA) (plus (regA) (const_int)))
2463 We would like to extract
2464 regA and regB (or const_int) from plus rtx. */
2465 op0
= XEXP (XEXP (x
, 1), 0);
2466 op1
= XEXP (XEXP (x
, 1), 1);
2468 /* Checking op0, forbid using static chain register ($r16)
2469 on reduced-set registers configuration. */
2470 if (TARGET_REDUCED_REGS
2472 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2473 sorry ("a nested function is not supported for reduced registers");
2474 /* Checking op1, forbid using static chain register ($r16)
2475 on reduced-set registers configuration. */
2476 if (TARGET_REDUCED_REGS
2478 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
2479 sorry ("a nested function is not supported for reduced registers");
2481 if (REG_P (op0
) && REG_P (op1
))
2484 fprintf (stream
, "[%s], %s",
2485 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
2487 else if (REG_P (op0
) && CONST_INT_P (op1
))
2490 fprintf (stream
, "[%s], %d",
2491 reg_names
[REGNO (op0
)], (int)INTVAL (op1
));
2495 /* The control flow is not supposed to be here. */
2506 /* Checking op0, forbid using static chain register ($r16)
2507 on reduced-set registers configuration. */
2508 if (TARGET_REDUCED_REGS
2510 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2511 sorry ("a nested function is not supported for reduced registers");
2515 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2516 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2517 We only need to deal with register Ra. */
2518 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
2522 /* The control flow is not supposed to be here. */
2530 /* Generally, output_addr_const () is able to handle most cases.
2531 We want to see what CODE could appear,
2532 so we use gcc_unreachable() to stop it. */
2540 /* Defining target-specific uses of __attribute__. */
2542 /* Add some checking after merging attributes. */
2544 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
2546 tree combined_attrs
;
2548 /* Create combined attributes. */
2549 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
2550 DECL_ATTRIBUTES (newdecl
));
2552 /* Since newdecl is acutally a duplicate of olddecl,
2553 we can take olddecl for some operations. */
2554 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
2556 /* Check isr-specific attributes conflict. */
2557 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
2560 return combined_attrs
;
2563 /* Add some checking when inserting attributes. */
2565 nds32_insert_attributes (tree decl
, tree
*attributes
)
2567 /* For function declaration, we need to check isr-specific attributes:
2568 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2569 2. Check valid integer value for interrupt/exception.
2570 3. Check valid integer value for reset.
2571 4. Check valid function for nmi/warm. */
2572 if (TREE_CODE (decl
) == FUNCTION_DECL
)
2575 tree intr
, excp
, reset
;
2577 /* Pick up function attributes. */
2578 func_attrs
= *attributes
;
2580 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2581 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
2583 /* Now we are starting to check valid id value
2584 for interrupt/exception/reset.
2585 Note that we ONLY check its validity here.
2586 To construct isr vector information, it is still performed
2587 by nds32_construct_isr_vectors_information(). */
2588 intr
= lookup_attribute ("interrupt", func_attrs
);
2589 excp
= lookup_attribute ("exception", func_attrs
);
2590 reset
= lookup_attribute ("reset", func_attrs
);
2594 /* Deal with interrupt/exception. */
2596 unsigned int lower_bound
, upper_bound
;
2598 /* The way to handle interrupt or exception is the same,
2599 we just need to take care of actual vector number.
2600 For interrupt(0..63), the actual vector number is (9..72).
2601 For exception(1..8), the actual vector number is (1..8). */
2602 lower_bound
= (intr
) ? (0) : (1);
2603 upper_bound
= (intr
) ? (63) : (8);
2605 /* Prepare id list so that we can traverse id value. */
2606 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
2608 /* 2. Check valid integer value for interrupt/exception. */
2613 /* Pick up each vector id value. */
2614 id
= TREE_VALUE (id_list
);
2615 /* Issue error if it is not a valid integer value. */
2616 if (TREE_CODE (id
) != INTEGER_CST
2617 || wi::ltu_p (id
, lower_bound
)
2618 || wi::gtu_p (id
, upper_bound
))
2619 error ("invalid id value for interrupt/exception attribute");
2621 /* Advance to next id. */
2622 id_list
= TREE_CHAIN (id_list
);
2627 /* Deal with reset. */
2631 unsigned int lower_bound
;
2632 unsigned int upper_bound
;
2634 /* Prepare id_list and identify id value so that
2635 we can check if total number of vectors is valid. */
2636 id_list
= TREE_VALUE (reset
);
2637 id
= TREE_VALUE (id_list
);
2639 /* The maximum numbers for user's interrupt is 64. */
2643 /* 3. Check valid integer value for reset. */
2644 if (TREE_CODE (id
) != INTEGER_CST
2645 || wi::ltu_p (id
, lower_bound
)
2646 || wi::gtu_p (id
, upper_bound
))
2647 error ("invalid id value for reset attribute");
2649 /* 4. Check valid function for nmi/warm. */
2650 nmi
= lookup_attribute ("nmi", func_attrs
);
2651 warm
= lookup_attribute ("warm", func_attrs
);
2653 if (nmi
!= NULL_TREE
)
2658 nmi_func_list
= TREE_VALUE (nmi
);
2659 nmi_func
= TREE_VALUE (nmi_func_list
);
2661 /* Issue error if it is not a valid nmi function. */
2662 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
2663 error ("invalid nmi function for reset attribute");
2666 if (warm
!= NULL_TREE
)
2668 tree warm_func_list
;
2671 warm_func_list
= TREE_VALUE (warm
);
2672 warm_func
= TREE_VALUE (warm_func_list
);
2674 /* Issue error if it is not a valid warm function. */
2675 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
2676 error ("invalid warm function for reset attribute");
2681 /* No interrupt, exception, or reset attribute is set. */
2688 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
2689 tree pop_target ATTRIBUTE_UNUSED
)
2691 /* Currently, we do not parse any pragma target by ourself,
2692 so just simply return false. */
2697 nds32_option_override (void)
2699 /* After all the command options have been parsed,
2700 we shall deal with some flags for changing compiler settings. */
2702 /* At first, we check if we have to strictly
2703 set some flags based on ISA family. */
2706 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2707 target_flags
&= ~MASK_V3PUSH
;
2711 /* Under V3 ISA, currently nothing should be strictly set. */
2715 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2716 target_flags
|= MASK_REDUCED_REGS
;
2717 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2718 target_flags
&= ~MASK_PERF_EXT
;
2721 /* See if we are using reduced-set registers:
2722 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2723 If so, we must forbid using $r11~$r14, $r16~$r27. */
2724 if (TARGET_REDUCED_REGS
)
2728 /* Prevent register allocator from
2729 choosing it as doing register allocation. */
2730 for (r
= 11; r
<= 14; r
++)
2731 fixed_regs
[r
] = call_used_regs
[r
] = 1;
2732 for (r
= 16; r
<= 27; r
++)
2733 fixed_regs
[r
] = call_used_regs
[r
] = 1;
2738 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2739 target_flags
&= ~MASK_V3PUSH
;
2742 /* Currently, we don't support PIC code generation yet. */
2744 sorry ("not support -fpic");
2748 /* Miscellaneous Parameters. */
2751 nds32_init_builtins (void)
2753 nds32_init_builtins_impl ();
2757 nds32_expand_builtin (tree exp
,
2763 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
2767 /* ------------------------------------------------------------------------ */
2769 /* PART 4: Implemet extern function definitions,
2770 the prototype is in nds32-protos.h. */
2772 /* Defining Data Structures for Per-function Information. */
2775 nds32_init_expanders (void)
2777 /* Arrange to initialize and mark the machine per-function status. */
2778 init_machine_status
= nds32_init_machine_status
;
2782 /* Register Usage. */
2784 /* -- How Values Fit in Registers. */
2787 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED
,
2790 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
2794 nds32_hard_regno_mode_ok (int regno
, machine_mode mode
)
2796 /* Restrict double-word quantities to even register pairs. */
2797 if (HARD_REGNO_NREGS (regno
, mode
) == 1
2805 /* Register Classes. */
2808 nds32_regno_reg_class (int regno
)
2810 /* Refer to nds32.h for more register class details. */
2812 if (regno
>= 0 && regno
<= 7)
2814 else if (regno
>= 8 && regno
<= 11)
2816 else if (regno
>= 12 && regno
<= 14)
2818 else if (regno
== 15)
2820 else if (regno
>= 16 && regno
<= 19)
2822 else if (regno
>= 20 && regno
<= 31)
2824 else if (regno
== 32 || regno
== 33)
2831 /* Stack Layout and Calling Conventions. */
2833 /* -- Basic Stack Layout. */
2836 nds32_return_addr_rtx (int count
,
2837 rtx frameaddr ATTRIBUTE_UNUSED
)
2839 /* There is no way to determine the return address
2840 if frameaddr is the frame that has 'count' steps
2841 up from current frame. */
2845 /* If count == 0, it means we are at current frame,
2846 the return address is $r30 ($lp). */
2847 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
2850 /* -- Eliminating Frame Pointer and Arg Pointer. */
2853 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
2855 HOST_WIDE_INT offset
;
2857 /* Compute and setup stack frame size.
2858 The result will be in cfun->machine. */
2859 nds32_compute_stack_frame ();
2861 /* Remember to consider
2862 cfun->machine->callee_saved_area_padding_bytes
2863 when calculating offset. */
2864 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
2866 offset
= (cfun
->machine
->fp_size
2867 + cfun
->machine
->gp_size
2868 + cfun
->machine
->lp_size
2869 + cfun
->machine
->callee_saved_gpr_regs_size
2870 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
2871 + cfun
->machine
->local_size
2872 + cfun
->machine
->out_args_size
);
2874 else if (from_reg
== ARG_POINTER_REGNUM
2875 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
2879 else if (from_reg
== FRAME_POINTER_REGNUM
2880 && to_reg
== STACK_POINTER_REGNUM
)
2882 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
2884 else if (from_reg
== FRAME_POINTER_REGNUM
2885 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
2887 offset
= (-1) * (cfun
->machine
->fp_size
2888 + cfun
->machine
->gp_size
2889 + cfun
->machine
->lp_size
2890 + cfun
->machine
->callee_saved_gpr_regs_size
2891 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
);
2901 /* -- Passing Arguments in Registers. */
2904 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
2905 tree fntype ATTRIBUTE_UNUSED
,
2906 rtx libname ATTRIBUTE_UNUSED
,
2907 tree fndecl ATTRIBUTE_UNUSED
,
2908 int n_named_args ATTRIBUTE_UNUSED
)
2910 /* Initial available registers
2911 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2912 for passing arguments. */
2913 cum
->gpr_offset
= 0;
2916 /* -- Function Entry and Exit. */
2918 /* Function for normal multiple push prologue. */
2920 nds32_expand_prologue (void)
2927 rtx fp_adjust_insn
, sp_adjust_insn
;
2929 /* Compute and setup stack frame size.
2930 The result will be in cfun->machine. */
2931 nds32_compute_stack_frame ();
2933 /* If this is a variadic function, first we need to push argument
2934 registers that hold the unnamed argument value. */
2935 if (cfun
->machine
->va_args_size
!= 0)
2937 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->va_args_first_regno
);
2938 Re
= gen_rtx_REG (SImode
, cfun
->machine
->va_args_last_regno
);
2939 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2940 nds32_emit_stack_push_multiple (Rb
, Re
, GEN_INT (0), true);
2942 /* We may also need to adjust stack pointer for padding bytes
2943 because varargs may cause $sp not 8-byte aligned. */
2944 if (cfun
->machine
->va_args_area_padding_bytes
)
2946 /* Generate sp adjustment instruction. */
2947 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
2948 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
2950 GEN_INT (-1 * sp_adjust
));
2952 /* Emit rtx into instructions list and receive INSN rtx form. */
2953 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
2955 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2956 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2957 generate CFI (Call Frame Information) stuff. */
2958 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
2962 /* If the function is 'naked',
2963 we do not have to generate prologue code fragment. */
2964 if (cfun
->machine
->naked_p
)
2967 /* Get callee_first_regno and callee_last_regno. */
2968 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_first_gpr_regno
);
2969 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_last_gpr_regno
);
2971 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2972 the pattern 'stack_push_multiple' is implemented in nds32.md.
2973 For En4 field, we have to calculate its constant value.
2974 Refer to Andes ISA for more information. */
2976 if (cfun
->machine
->fp_size
)
2978 if (cfun
->machine
->gp_size
)
2980 if (cfun
->machine
->lp_size
)
2983 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2984 to be saved, we don't have to create multiple push instruction.
2985 Otherwise, a multiple push instruction is needed. */
2986 if (!(REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
&& en4_const
== 0))
2988 /* Create multiple push instruction rtx. */
2989 nds32_emit_stack_push_multiple (Rb
, Re
, GEN_INT (en4_const
), false);
2992 /* Check frame_pointer_needed to see
2993 if we shall emit fp adjustment instruction. */
2994 if (frame_pointer_needed
)
2996 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2997 + (4 * callee-saved-registers)
2998 Note: No need to adjust
2999 cfun->machine->callee_saved_area_padding_bytes,
3000 because, at this point, stack pointer is just
3001 at the position after push instruction. */
3002 fp_adjust
= cfun
->machine
->fp_size
3003 + cfun
->machine
->gp_size
3004 + cfun
->machine
->lp_size
3005 + cfun
->machine
->callee_saved_gpr_regs_size
;
3006 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
3008 GEN_INT (fp_adjust
));
3009 /* Emit rtx into instructions list and receive INSN rtx form. */
3010 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
3012 /* The insn rtx 'fp_adjust_insn' will change frame layout. */
3013 RTX_FRAME_RELATED_P (fp_adjust_insn
) = 1;
3016 /* Adjust $sp = $sp - local_size - out_args_size
3017 - callee_saved_area_padding_bytes. */
3018 sp_adjust
= cfun
->machine
->local_size
3019 + cfun
->machine
->out_args_size
3020 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
3021 /* sp_adjust value may be out of range of the addi instruction,
3022 create alternative add behavior with TA_REGNUM if necessary,
3023 using NEGATIVE value to tell that we are decreasing address. */
3024 sp_adjust
= nds32_force_addi_stack_int ( (-1) * sp_adjust
);
3027 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
3028 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3030 GEN_INT (-1 * sp_adjust
));
3031 /* Emit rtx into instructions list and receive INSN rtx form. */
3032 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3034 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3035 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3036 generate CFI (Call Frame Information) stuff. */
3037 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3040 /* Prevent the instruction scheduler from
3041 moving instructions across the boundary. */
3042 emit_insn (gen_blockage ());
3045 /* Function for normal multiple pop epilogue. */
3047 nds32_expand_epilogue (bool sibcall_p
)
3055 /* Compute and setup stack frame size.
3056 The result will be in cfun->machine. */
3057 nds32_compute_stack_frame ();
3059 /* Prevent the instruction scheduler from
3060 moving instructions across the boundary. */
3061 emit_insn (gen_blockage ());
3063 /* If the function is 'naked', we do not have to generate
3064 epilogue code fragment BUT 'ret' instruction.
3065 However, if this function is also a variadic function,
3066 we need to create adjust stack pointer before 'ret' instruction. */
3067 if (cfun
->machine
->naked_p
)
3069 /* If this is a variadic function, we do not have to restore argument
3070 registers but need to adjust stack pointer back to previous stack
3071 frame location before return. */
3072 if (cfun
->machine
->va_args_size
!= 0)
3074 /* Generate sp adjustment instruction.
3075 We need to consider padding bytes here. */
3076 sp_adjust
= cfun
->machine
->va_args_size
3077 + cfun
->machine
->va_args_area_padding_bytes
;
3078 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3080 GEN_INT (sp_adjust
));
3081 /* Emit rtx into instructions list and receive INSN rtx form. */
3082 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3084 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3085 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3086 generate CFI (Call Frame Information) stuff. */
3087 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3090 /* Generate return instruction by using 'return_internal' pattern.
3091 Make sure this instruction is after gen_blockage(). */
3093 emit_jump_insn (gen_return_internal ());
3097 if (frame_pointer_needed
)
3099 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3100 - (4 * callee-saved-registers)
3101 Note: No need to adjust
3102 cfun->machine->callee_saved_area_padding_bytes,
3103 because we want to adjust stack pointer
3104 to the position for pop instruction. */
3105 sp_adjust
= cfun
->machine
->fp_size
3106 + cfun
->machine
->gp_size
3107 + cfun
->machine
->lp_size
3108 + cfun
->machine
->callee_saved_gpr_regs_size
;
3109 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3110 hard_frame_pointer_rtx
,
3111 GEN_INT (-1 * sp_adjust
));
3112 /* Emit rtx into instructions list and receive INSN rtx form. */
3113 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3115 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3116 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3120 /* If frame pointer is NOT needed,
3121 we cannot calculate the sp adjustment from frame pointer.
3122 Instead, we calculate the adjustment by local_size,
3123 out_args_size, and callee_saved_area_padding_bytes.
3124 Notice that such sp adjustment value may be out of range,
3125 so we have to deal with it as well. */
3127 /* Adjust $sp = $sp + local_size + out_args_size
3128 + callee_saved_area_padding_bytes. */
3129 sp_adjust
= cfun
->machine
->local_size
3130 + cfun
->machine
->out_args_size
3131 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
3132 /* sp_adjust value may be out of range of the addi instruction,
3133 create alternative add behavior with TA_REGNUM if necessary,
3134 using POSITIVE value to tell that we are increasing address. */
3135 sp_adjust
= nds32_force_addi_stack_int (sp_adjust
);
3138 /* Generate sp adjustment instruction
3139 if and only if sp_adjust != 0. */
3140 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3142 GEN_INT (sp_adjust
));
3143 /* Emit rtx into instructions list and receive INSN rtx form. */
3144 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3146 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3147 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3151 /* Get callee_first_regno and callee_last_regno. */
3152 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_first_gpr_regno
);
3153 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_last_gpr_regno
);
3155 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3156 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3157 For En4 field, we have to calculate its constant value.
3158 Refer to Andes ISA for more information. */
3160 if (cfun
->machine
->fp_size
)
3162 if (cfun
->machine
->gp_size
)
3164 if (cfun
->machine
->lp_size
)
3167 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3168 to be saved, we don't have to create multiple pop instruction.
3169 Otherwise, a multiple pop instruction is needed. */
3170 if (!(REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
&& en4_const
== 0))
3172 /* Create multiple pop instruction rtx. */
3173 nds32_emit_stack_pop_multiple (Rb
, Re
, GEN_INT (en4_const
));
3176 /* If this is a variadic function, we do not have to restore argument
3177 registers but need to adjust stack pointer back to previous stack
3178 frame location before return. */
3179 if (cfun
->machine
->va_args_size
!= 0)
3181 /* Generate sp adjustment instruction.
3182 We need to consider padding bytes here. */
3183 sp_adjust
= cfun
->machine
->va_args_size
3184 + cfun
->machine
->va_args_area_padding_bytes
;
3185 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3187 GEN_INT (sp_adjust
));
3188 /* Emit rtx into instructions list and receive INSN rtx form. */
3189 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3191 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3192 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3193 generate CFI (Call Frame Information) stuff. */
3194 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3197 /* Generate return instruction. */
3199 emit_jump_insn (gen_return_internal ());
3202 /* Function for v3push prologue. */
3204 nds32_expand_prologue_v3push (void)
3210 rtx fp_adjust_insn
, sp_adjust_insn
;
3212 /* Compute and setup stack frame size.
3213 The result will be in cfun->machine. */
3214 nds32_compute_stack_frame ();
3216 /* If the function is 'naked',
3217 we do not have to generate prologue code fragment. */
3218 if (cfun
->machine
->naked_p
)
3221 /* Get callee_first_regno and callee_last_regno. */
3222 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_first_gpr_regno
);
3223 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_last_gpr_regno
);
3225 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3226 where imm8u has to be 8-byte alignment. */
3227 sp_adjust
= cfun
->machine
->local_size
3228 + cfun
->machine
->out_args_size
3229 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
3231 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
3232 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
3234 /* We can use 'push25 Re,imm8u'. */
3236 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3237 the pattern 'stack_v3push' is implemented in nds32.md.
3238 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3239 nds32_emit_stack_v3push (Rb
, Re
,
3240 GEN_INT (14), GEN_INT (sp_adjust
));
3242 /* Check frame_pointer_needed to see
3243 if we shall emit fp adjustment instruction. */
3244 if (frame_pointer_needed
)
3246 /* adjust $fp = $sp + 4 ($fp size)
3249 + (4 * n) (callee-saved registers)
3250 + sp_adjust ('push25 Re,imm8u')
3251 Note: Since we use 'push25 Re,imm8u',
3252 the position of stack pointer is further
3253 changed after push instruction.
3254 Hence, we need to take sp_adjust value
3255 into consideration. */
3256 fp_adjust
= cfun
->machine
->fp_size
3257 + cfun
->machine
->gp_size
3258 + cfun
->machine
->lp_size
3259 + cfun
->machine
->callee_saved_gpr_regs_size
3261 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
3263 GEN_INT (fp_adjust
));
3264 /* Emit rtx into instructions list and receive INSN rtx form. */
3265 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
3270 /* We have to use 'push25 Re,0' and
3271 expand one more instruction to adjust $sp later. */
3273 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3274 the pattern 'stack_v3push' is implemented in nds32.md.
3275 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3276 nds32_emit_stack_v3push (Rb
, Re
,
3277 GEN_INT (14), GEN_INT (0));
3279 /* Check frame_pointer_needed to see
3280 if we shall emit fp adjustment instruction. */
3281 if (frame_pointer_needed
)
3283 /* adjust $fp = $sp + 4 ($fp size)
3286 + (4 * n) (callee-saved registers)
3287 Note: Since we use 'push25 Re,0',
3288 the stack pointer is just at the position
3289 after push instruction.
3290 No need to take sp_adjust into consideration. */
3291 fp_adjust
= cfun
->machine
->fp_size
3292 + cfun
->machine
->gp_size
3293 + cfun
->machine
->lp_size
3294 + cfun
->machine
->callee_saved_gpr_regs_size
;
3295 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
3297 GEN_INT (fp_adjust
));
3298 /* Emit rtx into instructions list and receive INSN rtx form. */
3299 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
3302 /* Because we use 'push25 Re,0',
3303 we need to expand one more instruction to adjust $sp.
3304 However, sp_adjust value may be out of range of the addi instruction,
3305 create alternative add behavior with TA_REGNUM if necessary,
3306 using NEGATIVE value to tell that we are decreasing address. */
3307 sp_adjust
= nds32_force_addi_stack_int ( (-1) * sp_adjust
);
3310 /* Generate sp adjustment instruction
3311 if and only if sp_adjust != 0. */
3312 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3314 GEN_INT (-1 * sp_adjust
));
3315 /* Emit rtx into instructions list and receive INSN rtx form. */
3316 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3318 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3319 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3320 generate CFI (Call Frame Information) stuff. */
3321 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3325 /* Prevent the instruction scheduler from
3326 moving instructions across the boundary. */
3327 emit_insn (gen_blockage ());
3330 /* Function for v3pop epilogue. */
3332 nds32_expand_epilogue_v3pop (bool sibcall_p
)
3339 /* Compute and setup stack frame size.
3340 The result will be in cfun->machine. */
3341 nds32_compute_stack_frame ();
3343 /* Prevent the instruction scheduler from
3344 moving instructions across the boundary. */
3345 emit_insn (gen_blockage ());
3347 /* If the function is 'naked', we do not have to generate
3348 epilogue code fragment BUT 'ret' instruction. */
3349 if (cfun
->machine
->naked_p
)
3351 /* Generate return instruction by using 'return_internal' pattern.
3352 Make sure this instruction is after gen_blockage(). */
3354 emit_jump_insn (gen_return_internal ());
3358 /* Get callee_first_regno and callee_last_regno. */
3359 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_first_gpr_regno
);
3360 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_last_gpr_regno
);
3362 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3363 where imm8u has to be 8-byte alignment. */
3364 sp_adjust
= cfun
->machine
->local_size
3365 + cfun
->machine
->out_args_size
3366 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
3368 /* We have to consider alloca issue as well.
3369 If the function does call alloca(), the stack pointer is not fixed.
3370 In that case, we cannot use 'pop25 Re,imm8u' directly.
3371 We have to caculate stack pointer from frame pointer
3372 and then use 'pop25 Re,0'.
3373 Of course, the frame_pointer_needed should be nonzero
3374 if the function calls alloca(). */
3375 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
3376 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
3377 && !cfun
->calls_alloca
)
3379 /* We can use 'pop25 Re,imm8u'. */
3381 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3382 the pattern 'stack_v3pop' is implementad in nds32.md.
3383 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3384 nds32_emit_stack_v3pop (Rb
, Re
,
3385 GEN_INT (14), GEN_INT (sp_adjust
));
3389 /* We have to use 'pop25 Re,0', and prior to it,
3390 we must expand one more instruction to adjust $sp. */
3392 if (frame_pointer_needed
)
3394 /* adjust $sp = $fp - 4 ($fp size)
3397 - (4 * n) (callee-saved registers)
3398 Note: No need to adjust
3399 cfun->machine->callee_saved_area_padding_bytes,
3400 because we want to adjust stack pointer
3401 to the position for pop instruction. */
3402 sp_adjust
= cfun
->machine
->fp_size
3403 + cfun
->machine
->gp_size
3404 + cfun
->machine
->lp_size
3405 + cfun
->machine
->callee_saved_gpr_regs_size
;
3406 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3407 hard_frame_pointer_rtx
,
3408 GEN_INT (-1 * sp_adjust
));
3409 /* Emit rtx into instructions list and receive INSN rtx form. */
3410 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3414 /* If frame pointer is NOT needed,
3415 we cannot calculate the sp adjustment from frame pointer.
3416 Instead, we calculate the adjustment by local_size,
3417 out_args_size, and callee_saved_area_padding_bytes.
3418 Notice that such sp adjustment value may be out of range,
3419 so we have to deal with it as well. */
3421 /* Adjust $sp = $sp + local_size + out_args_size
3422 + callee_saved_area_padding_bytes. */
3423 sp_adjust
= cfun
->machine
->local_size
3424 + cfun
->machine
->out_args_size
3425 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
3426 /* sp_adjust value may be out of range of the addi instruction,
3427 create alternative add behavior with TA_REGNUM if necessary,
3428 using POSITIVE value to tell that we are increasing address. */
3429 sp_adjust
= nds32_force_addi_stack_int (sp_adjust
);
3432 /* Generate sp adjustment instruction
3433 if and only if sp_adjust != 0. */
3434 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3436 GEN_INT (sp_adjust
));
3437 /* Emit rtx into instructions list and receive INSN rtx form. */
3438 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3442 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3443 the pattern 'stack_v3pop' is implementad in nds32.md. */
3444 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3445 nds32_emit_stack_v3pop (Rb
, Re
,
3446 GEN_INT (14), GEN_INT (0));
3449 /* Generate return instruction. */
3450 emit_jump_insn (gen_pop25return ());
3453 /* Return nonzero if this function is known to have a null epilogue.
3454 This allows the optimizer to omit jumps to jumps if no stack
3457 nds32_can_use_return_insn (void)
3459 /* Prior to reloading, we can't tell how many registers must be saved.
3460 Thus we can not determine whether this function has null epilogue. */
3461 if (!reload_completed
)
3464 /* If no stack was created, two conditions must be satisfied:
3465 1. This is a naked function.
3466 So there is no callee-saved, local size, or outgoing size.
3467 2. This is NOT a variadic function.
3468 So there is no pushing arguement registers into the stack. */
3469 return (cfun
->machine
->naked_p
&& (cfun
->machine
->va_args_size
== 0));
3472 /* ------------------------------------------------------------------------ */
3474 /* Function to test 333-form for load/store instructions.
3475 This is auxiliary extern function for auxiliary macro in nds32.h.
3476 Because it is a little complicated, we use function instead of macro. */
3478 nds32_ls_333_p (rtx rt
, rtx ra
, rtx imm
, machine_mode mode
)
3480 if (REGNO_REG_CLASS (REGNO (rt
)) == LOW_REGS
3481 && REGNO_REG_CLASS (REGNO (ra
)) == LOW_REGS
)
3483 if (GET_MODE_SIZE (mode
) == 4)
3484 return satisfies_constraint_Iu05 (imm
);
3486 if (GET_MODE_SIZE (mode
) == 2)
3487 return satisfies_constraint_Iu04 (imm
);
3489 if (GET_MODE_SIZE (mode
) == 1)
3490 return satisfies_constraint_Iu03 (imm
);
3497 /* Computing the Length of an Insn.
3498 Modifies the length assigned to instruction INSN.
3499 LEN is the initially computed length of the insn. */
3501 nds32_adjust_insn_length (rtx_insn
*insn
, int length
)
3505 switch (recog_memoized (insn
))
3507 case CODE_FOR_move_df
:
3508 case CODE_FOR_move_di
:
3509 /* Adjust length of movd44 to 2. */
3510 src
= XEXP (PATTERN (insn
), 1);
3511 dst
= XEXP (PATTERN (insn
), 0);
3515 && (REGNO (src
) % 2) == 0
3516 && (REGNO (dst
) % 2) == 0)
3528 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3530 nds32_target_alignment (rtx label
)
3537 insn
= next_active_insn (label
);
3541 else if ((get_attr_length (insn
) % 4) == 0)
3547 /* ------------------------------------------------------------------------ */
3549 /* PART 5: Initialize target hook structure and definitions. */
3551 /* Controlling the Compilation Driver. */
3554 /* Run-time Target Specification. */
3557 /* Defining Data Structures for Per-function Information. */
3560 /* Storage Layout. */
3562 #undef TARGET_PROMOTE_FUNCTION_MODE
3563 #define TARGET_PROMOTE_FUNCTION_MODE \
3564 default_promote_function_mode_always_promote
3567 /* Layout of Source Language Data Types. */
3570 /* Register Usage. */
3572 /* -- Basic Characteristics of Registers. */
3574 /* -- Order of Allocation of Registers. */
3576 /* -- How Values Fit in Registers. */
3578 /* -- Handling Leaf Functions. */
3580 /* -- Registers That Form a Stack. */
3583 /* Register Classes. */
3585 #undef TARGET_CLASS_MAX_NREGS
3586 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3589 #define TARGET_LRA_P hook_bool_void_true
3591 #undef TARGET_REGISTER_PRIORITY
3592 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3595 /* Obsolete Macros for Defining Constraints. */
3598 /* Stack Layout and Calling Conventions. */
3600 /* -- Basic Stack Layout. */
3602 /* -- Exception Handling Support. */
3604 /* -- Specifying How Stack Checking is Done. */
3606 /* -- Registers That Address the Stack Frame. */
3608 /* -- Eliminating Frame Pointer and Arg Pointer. */
3610 #undef TARGET_CAN_ELIMINATE
3611 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3613 /* -- Passing Function Arguments on the Stack. */
3615 /* -- Passing Arguments in Registers. */
3617 #undef TARGET_FUNCTION_ARG
3618 #define TARGET_FUNCTION_ARG nds32_function_arg
3620 #undef TARGET_MUST_PASS_IN_STACK
3621 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3623 #undef TARGET_ARG_PARTIAL_BYTES
3624 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3626 #undef TARGET_FUNCTION_ARG_ADVANCE
3627 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3629 #undef TARGET_FUNCTION_ARG_BOUNDARY
3630 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3632 /* -- How Scalar Function Values Are Returned. */
3634 #undef TARGET_FUNCTION_VALUE
3635 #define TARGET_FUNCTION_VALUE nds32_function_value
3637 #undef TARGET_LIBCALL_VALUE
3638 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3640 #undef TARGET_FUNCTION_VALUE_REGNO_P
3641 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3643 /* -- How Large Values Are Returned. */
3645 /* -- Caller-Saves Register Allocation. */
3647 /* -- Function Entry and Exit. */
3649 #undef TARGET_ASM_FUNCTION_PROLOGUE
3650 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3652 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3653 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3655 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3656 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3658 #undef TARGET_ASM_FUNCTION_EPILOGUE
3659 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3661 #undef TARGET_ASM_OUTPUT_MI_THUNK
3662 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3664 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3665 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3667 /* -- Generating Code for Profiling. */
3669 /* -- Permitting tail calls. */
3671 #undef TARGET_WARN_FUNC_RETURN
3672 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3674 /* Stack smashing protection. */
3677 /* Implementing the Varargs Macros. */
3679 #undef TARGET_SETUP_INCOMING_VARARGS
3680 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3682 #undef TARGET_STRICT_ARGUMENT_NAMING
3683 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3686 /* Trampolines for Nested Functions. */
3688 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3689 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3691 #undef TARGET_TRAMPOLINE_INIT
3692 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3695 /* Implicit Calls to Library Routines. */
3698 /* Addressing Modes. */
3700 #undef TARGET_LEGITIMATE_ADDRESS_P
3701 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3704 /* Anchored Addresses. */
3707 /* Condition Code Status. */
3709 /* -- Representation of condition codes using (cc0). */
3711 /* -- Representation of condition codes using registers. */
3713 /* -- Macros to control conditional execution. */
3716 /* Describing Relative Costs of Operations. */
3718 #undef TARGET_REGISTER_MOVE_COST
3719 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3721 #undef TARGET_MEMORY_MOVE_COST
3722 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3724 #undef TARGET_RTX_COSTS
3725 #define TARGET_RTX_COSTS nds32_rtx_costs
3727 #undef TARGET_ADDRESS_COST
3728 #define TARGET_ADDRESS_COST nds32_address_cost
3731 /* Adjusting the Instruction Scheduler. */
3734 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3736 #undef TARGET_ENCODE_SECTION_INFO
3737 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
3740 /* Position Independent Code. */
3743 /* Defining the Output Assembler Language. */
3745 /* -- The Overall Framework of an Assembler File. */
3747 #undef TARGET_ASM_FILE_START
3748 #define TARGET_ASM_FILE_START nds32_asm_file_start
3749 #undef TARGET_ASM_FILE_END
3750 #define TARGET_ASM_FILE_END nds32_asm_file_end
3752 /* -- Output of Data. */
3754 #undef TARGET_ASM_ALIGNED_HI_OP
3755 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3757 #undef TARGET_ASM_ALIGNED_SI_OP
3758 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3760 /* -- Output of Uninitialized Variables. */
3762 /* -- Output and Generation of Labels. */
3764 #undef TARGET_ASM_GLOBALIZE_LABEL
3765 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3767 /* -- How Initialization Functions Are Handled. */
3769 /* -- Macros Controlling Initialization Routines. */
3771 /* -- Output of Assembler Instructions. */
3773 #undef TARGET_PRINT_OPERAND
3774 #define TARGET_PRINT_OPERAND nds32_print_operand
3775 #undef TARGET_PRINT_OPERAND_ADDRESS
3776 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3778 /* -- Output of Dispatch Tables. */
3780 /* -- Assembler Commands for Exception Regions. */
3782 /* -- Assembler Commands for Alignment. */
3785 /* Controlling Debugging Information Format. */
3787 /* -- Macros Affecting All Debugging Formats. */
3789 /* -- Specific Options for DBX Output. */
3791 /* -- Open-Ended Hooks for DBX Format. */
3793 /* -- File Names in DBX Format. */
3795 /* -- Macros for SDB and DWARF Output. */
3797 /* -- Macros for VMS Debug Format. */
3800 /* Cross Compilation and Floating Point. */
3803 /* Mode Switching Instructions. */
3806 /* Defining target-specific uses of __attribute__. */
3808 #undef TARGET_ATTRIBUTE_TABLE
3809 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3811 #undef TARGET_MERGE_DECL_ATTRIBUTES
3812 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3814 #undef TARGET_INSERT_ATTRIBUTES
3815 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3817 #undef TARGET_OPTION_PRAGMA_PARSE
3818 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3820 #undef TARGET_OPTION_OVERRIDE
3821 #define TARGET_OPTION_OVERRIDE nds32_option_override
3824 /* Emulating TLS. */
3827 /* Defining coprocessor specifics for MIPS targets. */
3830 /* Parameters for Precompiled Header Validity Checking. */
3833 /* C++ ABI parameters. */
3836 /* Adding support for named address spaces. */
3839 /* Miscellaneous Parameters. */
3841 #undef TARGET_INIT_BUILTINS
3842 #define TARGET_INIT_BUILTINS nds32_init_builtins
3844 #undef TARGET_EXPAND_BUILTIN
3845 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3848 /* ------------------------------------------------------------------------ */
3850 /* Initialize the GCC target structure. */
3852 struct gcc_target targetm
= TARGET_INITIALIZER
;
3854 /* ------------------------------------------------------------------------ */