1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2014 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
25 #include "coretypes.h"
28 #include "stor-layout.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h" /* Required by recog.h. */
35 #include "conditions.h"
37 #include "insn-attr.h" /* For DFA state_t. */
38 #include "insn-codes.h" /* For CODE_FOR_xxx. */
39 #include "reload.h" /* For push_reload(). */
49 #include "diagnostic-core.h"
52 #include "tm-constrs.h"
53 #include "optabs.h" /* For GEN_FCN. */
55 #include "target-def.h"
56 #include "langhooks.h" /* For add_builtin_function(). */
60 /* ------------------------------------------------------------------------ */
62 /* This file is divided into five parts:
64 PART 1: Auxiliary static variable definitions and
65 target hook static variable definitions.
67 PART 2: Auxiliary static function definitions.
69 PART 3: Implement target hook stuff definitions.
71 PART 4: Implemet extern function definitions,
72 the prototype is in nds32-protos.h.
74 PART 5: Initialize target hook structure and definitions. */
76 /* ------------------------------------------------------------------------ */
78 /* PART 1: Auxiliary static variable definitions and
79 target hook static variable definitions. */
81 /* Define intrinsic register names.
82 Please refer to nds32_intrinsic.h file, the index is corresponding to
83 'enum nds32_intrinsic_registers' data type values.
84 NOTE that the base value starting from 1024. */
85 static const char * const nds32_intrinsic_register_names
[] =
87 "$PSW", "$IPSW", "$ITYPE", "$IPC"
90 /* Defining target-specific uses of __attribute__. */
91 static const struct attribute_spec nds32_attribute_table
[] =
93 /* Syntax: { name, min_len, max_len, decl_required, type_required,
94 function_type_required, handler, affects_type_identity } */
96 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
97 { "interrupt", 1, 64, false, false, false, NULL
, false },
98 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
99 { "exception", 1, 8, false, false, false, NULL
, false },
100 /* Argument is user's interrupt numbers. The vector number is always 0. */
101 { "reset", 1, 1, false, false, false, NULL
, false },
103 /* The attributes describing isr nested type. */
104 { "nested", 0, 0, false, false, false, NULL
, false },
105 { "not_nested", 0, 0, false, false, false, NULL
, false },
106 { "nested_ready", 0, 0, false, false, false, NULL
, false },
108 /* The attributes describing isr register save scheme. */
109 { "save_all", 0, 0, false, false, false, NULL
, false },
110 { "partial_save", 0, 0, false, false, false, NULL
, false },
112 /* The attributes used by reset attribute. */
113 { "nmi", 1, 1, false, false, false, NULL
, false },
114 { "warm", 1, 1, false, false, false, NULL
, false },
116 /* The attribute telling no prologue/epilogue. */
117 { "naked", 0, 0, false, false, false, NULL
, false },
119 /* The last attribute spec is set to be NULL. */
120 { NULL
, 0, 0, false, false, false, NULL
, false }
124 /* ------------------------------------------------------------------------ */
126 /* PART 2: Auxiliary static function definitions. */
128 /* Function to save and restore machine-specific function data. */
129 static struct machine_function
*
130 nds32_init_machine_status (void)
132 struct machine_function
*machine
;
133 machine
= ggc_cleared_alloc
<machine_function
> ();
135 /* Initially assume this function needs prologue/epilogue. */
136 machine
->naked_p
= 0;
138 /* Initially assume this function does NOT use fp_as_gp optimization. */
139 machine
->fp_as_gp_p
= 0;
144 /* Function to compute stack frame size and
145 store into cfun->machine structure. */
147 nds32_compute_stack_frame (void)
152 /* Because nds32_compute_stack_frame() will be called from different place,
153 everytime we enter this function, we have to assume this function
154 needs prologue/epilogue. */
155 cfun
->machine
->naked_p
= 0;
157 /* Get variadic arguments size to prepare pretend arguments and
158 we will push them into stack at prologue by ourself. */
159 cfun
->machine
->va_args_size
= crtl
->args
.pretend_args_size
;
160 if (cfun
->machine
->va_args_size
!= 0)
162 cfun
->machine
->va_args_first_regno
163 = NDS32_GPR_ARG_FIRST_REGNUM
164 + NDS32_MAX_GPR_REGS_FOR_ARGS
165 - (crtl
->args
.pretend_args_size
/ UNITS_PER_WORD
);
166 cfun
->machine
->va_args_last_regno
167 = NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
- 1;
171 cfun
->machine
->va_args_first_regno
= SP_REGNUM
;
172 cfun
->machine
->va_args_last_regno
= SP_REGNUM
;
175 /* Important: We need to make sure that varargs area is 8-byte alignment. */
176 block_size
= cfun
->machine
->va_args_size
;
177 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
179 cfun
->machine
->va_args_area_padding_bytes
180 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
183 /* Get local variables, incoming variables, and temporary variables size.
184 Note that we need to make sure it is 8-byte alignment because
185 there may be no padding bytes if we are using LRA. */
186 cfun
->machine
->local_size
= NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
188 /* Get outgoing arguments size. */
189 cfun
->machine
->out_args_size
= crtl
->outgoing_args_size
;
191 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
192 Check whether $fp is ever live. */
193 cfun
->machine
->fp_size
= (df_regs_ever_live_p (FP_REGNUM
)) ? 4 : 0;
195 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
196 Check whether we are using PIC code genration. */
197 cfun
->machine
->gp_size
= (flag_pic
) ? 4 : 0;
199 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
200 Check whether $lp is ever live. */
201 cfun
->machine
->lp_size
= (df_regs_ever_live_p (LP_REGNUM
)) ? 4 : 0;
203 /* Initially there is no padding bytes. */
204 cfun
->machine
->callee_saved_area_padding_bytes
= 0;
206 /* Calculate the bytes of saving callee-saved registers on stack. */
207 cfun
->machine
->callee_saved_regs_size
= 0;
208 cfun
->machine
->callee_saved_regs_first_regno
= SP_REGNUM
;
209 cfun
->machine
->callee_saved_regs_last_regno
= SP_REGNUM
;
210 /* Currently, there is no need to check $r28~$r31
211 because we will save them in another way. */
212 for (r
= 0; r
< 28; r
++)
214 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
216 /* Mark the first required callee-saved register
217 (only need to set it once).
218 If first regno == SP_REGNUM, we can tell that
219 it is the first time to be here. */
220 if (cfun
->machine
->callee_saved_regs_first_regno
== SP_REGNUM
)
221 cfun
->machine
->callee_saved_regs_first_regno
= r
;
222 /* Mark the last required callee-saved register. */
223 cfun
->machine
->callee_saved_regs_last_regno
= r
;
227 /* Check if this function can omit prologue/epilogue code fragment.
228 If there is 'naked' attribute in this function,
229 we can set 'naked_p' flag to indicate that
230 we do not have to generate prologue/epilogue.
231 Or, if all the following conditions succeed,
232 we can set this function 'naked_p' as well:
233 condition 1: first_regno == last_regno == SP_REGNUM,
234 which means we do not have to save
235 any callee-saved registers.
236 condition 2: Both $lp and $fp are NOT live in this function,
237 which means we do not need to save them and there
239 condition 3: There is no local_size, which means
240 we do not need to adjust $sp. */
241 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
))
242 || (cfun
->machine
->callee_saved_regs_first_regno
== SP_REGNUM
243 && cfun
->machine
->callee_saved_regs_last_regno
== SP_REGNUM
244 && !df_regs_ever_live_p (FP_REGNUM
)
245 && !df_regs_ever_live_p (LP_REGNUM
)
246 && cfun
->machine
->local_size
== 0))
248 /* Set this function 'naked_p' and other functions can check this flag.
249 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
250 callee-saved, local size, and outgoing size.
251 The varargs space and ret instruction may still present in
252 the prologue/epilogue expanding. */
253 cfun
->machine
->naked_p
= 1;
255 /* No need to save $fp, $gp, and $lp.
256 We should set these value to be zero
257 so that nds32_initial_elimination_offset() can work properly. */
258 cfun
->machine
->fp_size
= 0;
259 cfun
->machine
->gp_size
= 0;
260 cfun
->machine
->lp_size
= 0;
262 /* If stack usage computation is required,
263 we need to provide the static stack size. */
264 if (flag_stack_usage_info
)
265 current_function_static_stack_size
= 0;
267 /* No need to do following adjustment, return immediately. */
271 /* Adjustment for v3push instructions:
272 If we are using v3push (push25/pop25) instructions,
273 we need to make sure Rb is $r6 and Re is
274 located on $r6, $r8, $r10, or $r14.
275 Some results above will be discarded and recomputed.
276 Note that it is only available under V3/V3M ISA and we
277 DO NOT setup following stuff for isr or variadic function. */
279 && !nds32_isr_function_p (current_function_decl
)
280 && (cfun
->machine
->va_args_size
== 0))
283 cfun->machine->fp_size
284 cfun->machine->gp_size
285 cfun->machine->lp_size
286 cfun->machine->callee_saved_regs_first_regno
287 cfun->machine->callee_saved_regs_last_regno */
289 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
290 cfun
->machine
->fp_size
= 4;
291 cfun
->machine
->gp_size
= 4;
292 cfun
->machine
->lp_size
= 4;
294 /* Remember to set Rb = $r6. */
295 cfun
->machine
->callee_saved_regs_first_regno
= 6;
297 if (cfun
->machine
->callee_saved_regs_last_regno
<= 6)
300 cfun
->machine
->callee_saved_regs_last_regno
= 6;
302 else if (cfun
->machine
->callee_saved_regs_last_regno
<= 8)
305 cfun
->machine
->callee_saved_regs_last_regno
= 8;
307 else if (cfun
->machine
->callee_saved_regs_last_regno
<= 10)
310 cfun
->machine
->callee_saved_regs_last_regno
= 10;
312 else if (cfun
->machine
->callee_saved_regs_last_regno
<= 14)
315 cfun
->machine
->callee_saved_regs_last_regno
= 14;
317 else if (cfun
->machine
->callee_saved_regs_last_regno
== SP_REGNUM
)
319 /* If last_regno is SP_REGNUM, which means
320 it is never changed, so set it to Re = $r6. */
321 cfun
->machine
->callee_saved_regs_last_regno
= 6;
325 /* The program flow should not go here. */
330 /* We have correctly set callee_saved_regs_first_regno
331 and callee_saved_regs_last_regno.
332 Initially, the callee_saved_regs_size is supposed to be 0.
333 As long as callee_saved_regs_last_regno is not SP_REGNUM,
334 we can update callee_saved_regs_size with new size. */
335 if (cfun
->machine
->callee_saved_regs_last_regno
!= SP_REGNUM
)
337 /* Compute pushed size of callee-saved registers. */
338 cfun
->machine
->callee_saved_regs_size
339 = 4 * (cfun
->machine
->callee_saved_regs_last_regno
340 - cfun
->machine
->callee_saved_regs_first_regno
344 /* Important: We need to make sure that
345 (fp_size + gp_size + lp_size + callee_saved_regs_size)
347 If it is not, calculate the padding bytes. */
348 block_size
= cfun
->machine
->fp_size
349 + cfun
->machine
->gp_size
350 + cfun
->machine
->lp_size
351 + cfun
->machine
->callee_saved_regs_size
;
352 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
354 cfun
->machine
->callee_saved_area_padding_bytes
355 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
358 /* If stack usage computation is required,
359 we need to provide the static stack size. */
360 if (flag_stack_usage_info
)
362 current_function_static_stack_size
363 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
)
364 + cfun
->machine
->local_size
365 + cfun
->machine
->out_args_size
;
369 /* Function to create a parallel rtx pattern
370 which presents stack push multiple behavior.
371 The overall concept are:
372 "push registers to memory",
373 "adjust stack pointer". */
375 nds32_emit_stack_push_multiple (rtx Rb
, rtx Re
, rtx En4
)
382 int save_fp
, save_gp
, save_lp
;
390 /* We need to provide a customized rtx which contains
391 necessary information for data analysis,
392 so we create a parallel rtx like this:
393 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
395 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
398 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
400 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
402 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
404 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
406 (set (reg:SI SP_REGNUM)
407 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
409 /* Determine whether we need to save $fp, $gp, or $lp. */
410 save_fp
= INTVAL (En4
) & 0x8;
411 save_gp
= INTVAL (En4
) & 0x4;
412 save_lp
= INTVAL (En4
) & 0x2;
414 /* Calculate the number of registers that will be pushed. */
422 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
423 if (REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
)
424 num_use_regs
= extra_count
;
426 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + extra_count
;
428 /* In addition to used registers,
429 we need one more space for (set sp sp-x) rtx. */
430 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
431 rtvec_alloc (num_use_regs
+ 1));
434 /* Initialize offset and start to create push behavior. */
435 offset
= -(num_use_regs
* 4);
437 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
438 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
440 /* Rb and Re may be SP_REGNUM.
441 We need to break this loop immediately. */
442 if (regno
== SP_REGNUM
)
445 reg
= gen_rtx_REG (SImode
, regno
);
446 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
449 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
450 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
451 RTX_FRAME_RELATED_P (push_rtx
) = 1;
456 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
459 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
460 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
463 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
464 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
465 RTX_FRAME_RELATED_P (push_rtx
) = 1;
471 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
472 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
475 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
476 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
477 RTX_FRAME_RELATED_P (push_rtx
) = 1;
483 reg
= gen_rtx_REG (SImode
, LP_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;
494 /* Create (set sp sp-x). */
496 /* We need to re-calculate the offset value again for adjustment. */
497 offset
= -(num_use_regs
* 4);
499 = gen_rtx_SET (VOIDmode
,
501 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
502 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
503 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
505 parallel_insn
= emit_insn (parallel_insn
);
507 /* The insn rtx 'parallel_insn' will change frame layout.
508 We need to use RTX_FRAME_RELATED_P so that GCC is able to
509 generate CFI (Call Frame Information) stuff. */
510 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
513 /* Function to create a parallel rtx pattern
514 which presents stack pop multiple behavior.
515 The overall concept are:
516 "pop registers from memory",
517 "adjust stack pointer". */
519 nds32_emit_stack_pop_multiple (rtx Rb
, rtx Re
, rtx En4
)
526 int save_fp
, save_gp
, save_lp
;
533 rtx dwarf
= NULL_RTX
;
535 /* We need to provide a customized rtx which contains
536 necessary information for data analysis,
537 so we create a parallel rtx like this:
538 (parallel [(set (reg:SI Rb)
539 (mem (reg:SI SP_REGNUM)))
541 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
544 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
545 (set (reg:SI FP_REGNUM)
546 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
547 (set (reg:SI GP_REGNUM)
548 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
549 (set (reg:SI LP_REGNUM)
550 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
551 (set (reg:SI SP_REGNUM)
552 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
554 /* Determine whether we need to restore $fp, $gp, or $lp. */
555 save_fp
= INTVAL (En4
) & 0x8;
556 save_gp
= INTVAL (En4
) & 0x4;
557 save_lp
= INTVAL (En4
) & 0x2;
559 /* Calculate the number of registers that will be poped. */
567 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
568 if (REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
)
569 num_use_regs
= extra_count
;
571 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + extra_count
;
573 /* In addition to used registers,
574 we need one more space for (set sp sp+x) rtx. */
575 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
576 rtvec_alloc (num_use_regs
+ 1));
579 /* Initialize offset and start to create pop behavior. */
582 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
583 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
585 /* Rb and Re may be SP_REGNUM.
586 We need to break this loop immediately. */
587 if (regno
== SP_REGNUM
)
590 reg
= gen_rtx_REG (SImode
, regno
);
591 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
594 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
595 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
596 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
600 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
603 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
606 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
607 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
610 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
611 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
612 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
616 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
620 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
621 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
624 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
625 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
626 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
630 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
634 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
635 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
638 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
639 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
640 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
644 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
647 /* Create (set sp sp+x). */
649 /* The offset value is already in place. No need to re-calculate it. */
651 = gen_rtx_SET (VOIDmode
,
653 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
654 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
656 /* Tell gcc we adjust SP in this insn. */
657 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
659 parallel_insn
= emit_insn (parallel_insn
);
661 /* The insn rtx 'parallel_insn' will change frame layout.
662 We need to use RTX_FRAME_RELATED_P so that GCC is able to
663 generate CFI (Call Frame Information) stuff. */
664 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
666 /* Add CFI info by manual. */
667 REG_NOTES (parallel_insn
) = dwarf
;
670 /* Function to create a parallel rtx pattern
671 which presents stack v3push behavior.
672 The overall concept are:
673 "push registers to memory",
674 "adjust stack pointer". */
676 nds32_emit_stack_v3push (rtx Rb
,
678 rtx En4 ATTRIBUTE_UNUSED
,
692 /* We need to provide a customized rtx which contains
693 necessary information for data analysis,
694 so we create a parallel rtx like this:
695 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
697 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
700 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
702 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
704 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
706 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
708 (set (reg:SI SP_REGNUM)
709 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
711 /* Calculate the number of registers that will be pushed.
712 Since $fp, $gp, and $lp is always pushed with v3push instruction,
713 we need to count these three registers.
714 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
715 So there is no need to worry about Rb=Re=SP_REGNUM case. */
716 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + 3;
718 /* In addition to used registers,
719 we need one more space for (set sp sp-x-imm8u) rtx. */
720 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
721 rtvec_alloc (num_use_regs
+ 1));
724 /* Initialize offset and start to create push behavior. */
725 offset
= -(num_use_regs
* 4);
727 /* Create (set mem regX) from Rb, Rb+1 up to Re.
728 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
729 So there is no need to worry about Rb=Re=SP_REGNUM case. */
730 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
732 reg
= gen_rtx_REG (SImode
, regno
);
733 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
736 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
737 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
738 RTX_FRAME_RELATED_P (push_rtx
) = 1;
743 /* Create (set mem fp). */
744 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
745 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
748 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
749 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
750 RTX_FRAME_RELATED_P (push_rtx
) = 1;
753 /* Create (set mem gp). */
754 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
755 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
758 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
759 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
760 RTX_FRAME_RELATED_P (push_rtx
) = 1;
763 /* Create (set mem lp). */
764 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
765 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
768 push_rtx
= gen_rtx_SET (VOIDmode
, mem
, reg
);
769 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
770 RTX_FRAME_RELATED_P (push_rtx
) = 1;
774 /* Create (set sp sp-x-imm8u). */
776 /* We need to re-calculate the offset value again for adjustment. */
777 offset
= -(num_use_regs
* 4);
779 = gen_rtx_SET (VOIDmode
,
781 plus_constant (Pmode
,
783 offset
- INTVAL (imm8u
)));
784 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
785 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
787 parallel_insn
= emit_insn (parallel_insn
);
789 /* The insn rtx 'parallel_insn' will change frame layout.
790 We need to use RTX_FRAME_RELATED_P so that GCC is able to
791 generate CFI (Call Frame Information) stuff. */
792 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
795 /* Function to create a parallel rtx pattern
796 which presents stack v3pop behavior.
797 The overall concept are:
798 "pop registers from memory",
799 "adjust stack pointer". */
801 nds32_emit_stack_v3pop (rtx Rb
,
803 rtx En4 ATTRIBUTE_UNUSED
,
816 rtx dwarf
= NULL_RTX
;
818 /* We need to provide a customized rtx which contains
819 necessary information for data analysis,
820 so we create a parallel rtx like this:
821 (parallel [(set (reg:SI Rb)
822 (mem (reg:SI SP_REGNUM)))
824 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
827 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
828 (set (reg:SI FP_REGNUM)
829 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
830 (set (reg:SI GP_REGNUM)
831 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
832 (set (reg:SI LP_REGNUM)
833 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
834 (set (reg:SI SP_REGNUM)
835 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
837 /* Calculate the number of registers that will be poped.
838 Since $fp, $gp, and $lp is always poped with v3pop instruction,
839 we need to count these three registers.
840 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
841 So there is no need to worry about Rb=Re=SP_REGNUM case. */
842 num_use_regs
= REGNO (Re
) - REGNO (Rb
) + 1 + 3;
844 /* In addition to used registers,
845 we need one more space for (set sp sp+x+imm8u) rtx. */
846 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
847 rtvec_alloc (num_use_regs
+ 1));
850 /* Initialize offset and start to create pop behavior. */
853 /* Create (set regX mem) from Rb, Rb+1 up to Re.
854 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
855 So there is no need to worry about Rb=Re=SP_REGNUM case. */
856 for (regno
= REGNO (Rb
); regno
<= (int) REGNO (Re
); regno
++)
858 reg
= gen_rtx_REG (SImode
, regno
);
859 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
862 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
863 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
864 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
868 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
871 /* Create (set fp mem). */
872 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
873 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
876 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
877 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
878 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
881 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
883 /* Create (set gp mem). */
884 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
885 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
888 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
889 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
890 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
893 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
895 /* Create (set lp mem ). */
896 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
897 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
900 pop_rtx
= gen_rtx_SET (VOIDmode
, reg
, mem
);
901 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
902 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
905 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
907 /* Create (set sp sp+x+imm8u). */
909 /* The offset value is already in place. No need to re-calculate it. */
911 = gen_rtx_SET (VOIDmode
,
913 plus_constant (Pmode
,
915 offset
+ INTVAL (imm8u
)));
916 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
918 /* Tell gcc we adjust SP in this insn. */
919 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
921 parallel_insn
= emit_insn (parallel_insn
);
923 /* The insn rtx 'parallel_insn' will change frame layout.
924 We need to use RTX_FRAME_RELATED_P so that GCC is able to
925 generate CFI (Call Frame Information) stuff. */
926 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
928 /* Add CFI info by manual. */
929 REG_NOTES (parallel_insn
) = dwarf
;
932 /* Function that may creates more instructions
933 for large value on adjusting stack pointer.
935 In nds32 target, 'addi' can be used for stack pointer
936 adjustment in prologue/epilogue stage.
937 However, sometimes there are too many local variables so that
938 the adjustment value is not able to be fit in the 'addi' instruction.
939 One solution is to move value into a register
940 and then use 'add' instruction.
941 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
942 Also, we need to return zero for sp adjustment so that
943 proglogue/epilogue knows there is no need to create 'addi' instruction. */
945 nds32_force_addi_stack_int (int full_value
)
952 if (!satisfies_constraint_Is15 (GEN_INT (full_value
)))
954 /* The value is not able to fit in single addi instruction.
955 Create more instructions of moving value into a register
956 and then add stack pointer with it. */
958 /* $r15 is going to be temporary register to hold the value. */
959 tmp_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
961 /* Create one more instruction to move value
962 into the temporary register. */
963 emit_move_insn (tmp_reg
, GEN_INT (full_value
));
965 /* Create new 'add' rtx. */
966 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
969 /* Emit rtx into insn list and receive its transformed insn rtx. */
970 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
972 /* At prologue, we need to tell GCC that this is frame related insn,
973 so that we can consider this instruction to output debug information.
974 If full_value is NEGATIVE, it means this function
975 is invoked by expand_prologue. */
978 /* Because (tmp_reg <- full_value) may be split into two
979 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
980 We need to construct another (sp <- sp + full_value)
981 and then insert it into sp_adjust_insn's reg note to
982 represent a frame related expression.
983 GCC knows how to refer it and output debug information. */
988 plus_rtx
= plus_constant (Pmode
, stack_pointer_rtx
, full_value
);
989 set_rtx
= gen_rtx_SET (VOIDmode
, stack_pointer_rtx
, plus_rtx
);
990 add_reg_note (sp_adjust_insn
, REG_FRAME_RELATED_EXPR
, set_rtx
);
992 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
995 /* We have used alternative way to adjust stack pointer value.
996 Return zero so that prologue/epilogue
997 will not generate other instructions. */
1002 /* The value is able to fit in addi instruction.
1003 However, remember to make it to be positive value
1004 because we want to return 'adjustment' result. */
1005 adjust_value
= (full_value
< 0) ? (-full_value
) : (full_value
);
1007 return adjust_value
;
1011 /* Return true if MODE/TYPE need double word alignment. */
1013 nds32_needs_double_word_align (enum machine_mode mode
, const_tree type
)
1017 /* Pick up the alignment according to the mode or type. */
1018 align
= NDS32_MODE_TYPE_ALIGN (mode
, type
);
1020 return (align
> PARM_BOUNDARY
);
1023 /* Return true if FUNC is a naked function. */
1025 nds32_naked_function_p (tree func
)
1029 if (TREE_CODE (func
) != FUNCTION_DECL
)
1032 t
= lookup_attribute ("naked", DECL_ATTRIBUTES (func
));
1034 return (t
!= NULL_TREE
);
1037 /* Function that check if 'X' is a valid address register.
1038 The variable 'STRICT' is very important to
1039 make decision for register number.
1042 => We are in reload pass or after reload pass.
1043 The register number should be strictly limited in general registers.
1046 => Before reload pass, we are free to use any register number. */
1048 nds32_address_register_rtx_p (rtx x
, bool strict
)
1052 if (GET_CODE (x
) != REG
)
1058 return REGNO_OK_FOR_BASE_P (regno
);
1063 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1065 OUTER_MODE : Machine mode of outer address rtx.
1066 INDEX : Check if this rtx is valid to be a index for address.
1067 STRICT : If it is true, we are in reload pass or after reload pass. */
1069 nds32_legitimate_index_p (enum machine_mode outer_mode
,
1077 switch (GET_CODE (index
))
1080 regno
= REGNO (index
);
1081 /* If we are in reload pass or after reload pass,
1082 we need to limit it to general register. */
1084 return REGNO_OK_FOR_INDEX_P (regno
);
1089 /* The alignment of the integer value is determined by 'outer_mode'. */
1090 if (GET_MODE_SIZE (outer_mode
) == 1)
1092 /* Further check if the value is legal for the 'outer_mode'. */
1093 if (!satisfies_constraint_Is15 (index
))
1096 /* Pass all test, the value is valid, return true. */
1099 if (GET_MODE_SIZE (outer_mode
) == 2
1100 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index
)))
1102 /* Further check if the value is legal for the 'outer_mode'. */
1103 if (!satisfies_constraint_Is16 (index
))
1106 /* Pass all test, the value is valid, return true. */
1109 if (GET_MODE_SIZE (outer_mode
) == 4
1110 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1112 /* Further check if the value is legal for the 'outer_mode'. */
1113 if (!satisfies_constraint_Is17 (index
))
1116 /* Pass all test, the value is valid, return true. */
1119 if (GET_MODE_SIZE (outer_mode
) == 8
1120 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1122 /* Further check if the value is legal for the 'outer_mode'. */
1123 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index
) + 4,
1127 /* Pass all test, the value is valid, return true. */
1134 op0
= XEXP (index
, 0);
1135 op1
= XEXP (index
, 1);
1137 if (REG_P (op0
) && CONST_INT_P (op1
))
1140 multiplier
= INTVAL (op1
);
1142 /* We only allow (mult reg const_int_1)
1143 or (mult reg const_int_2) or (mult reg const_int_4). */
1144 if (multiplier
!= 1 && multiplier
!= 2 && multiplier
!= 4)
1147 regno
= REGNO (op0
);
1148 /* Limit it in general registers if we are
1149 in reload pass or after reload pass. */
1151 return REGNO_OK_FOR_INDEX_P (regno
);
1159 op0
= XEXP (index
, 0);
1160 op1
= XEXP (index
, 1);
1162 if (REG_P (op0
) && CONST_INT_P (op1
))
1165 /* op1 is already the sv value for use to do left shift. */
1168 /* We only allow (ashift reg const_int_0)
1169 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1170 if (sv
!= 0 && sv
!= 1 && sv
!=2)
1173 regno
= REGNO (op0
);
1174 /* Limit it in general registers if we are
1175 in reload pass or after reload pass. */
1177 return REGNO_OK_FOR_INDEX_P (regno
);
1189 /* ------------------------------------------------------------------------ */
1191 /* PART 3: Implement target hook stuff definitions. */
1193 /* Register Classes. */
1195 static unsigned char
1196 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED
,
1197 enum machine_mode mode
)
1199 /* Return the maximum number of consecutive registers
1200 needed to represent "mode" in a register of "rclass". */
1201 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
1205 nds32_register_priority (int hard_regno
)
1207 /* Encourage to use r0-r7 for LRA when optimize for size. */
1208 if (optimize_size
&& hard_regno
< 8)
1214 /* Stack Layout and Calling Conventions. */
1216 /* There are three kinds of pointer concepts using in GCC compiler:
1218 frame pointer: A pointer to the first location of local variables.
1219 stack pointer: A pointer to the top of a stack frame.
1220 argument pointer: A pointer to the incoming arguments.
1222 In nds32 target calling convention, we are using 8-byte alignment.
1223 Besides, we would like to have each stack frame of a function includes:
1226 1. previous hard frame pointer
1228 3. callee-saved registers
1229 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1231 cfun->machine->callee_saved_area_padding_bytes)
1235 2. spilling location
1236 3. <padding bytes> (it will be calculated by GCC itself)
1237 4. incoming arguments
1238 5. <padding bytes> (it will be calculated by GCC itself)
1241 1. <padding bytes> (it will be calculated by GCC itself)
1242 2. outgoing arguments
1244 We 'wrap' these blocks together with
1245 hard frame pointer ($r28) and stack pointer ($r31).
1246 By applying the basic frame/stack/argument pointers concept,
1247 the layout of a stack frame shoule be like this:
1250 old stack pointer -> ----
1252 | | saved arguments for
1253 | | vararg functions
1255 hard frame pointer -> --
1256 & argument pointer | | \
1257 | | previous hardware frame pointer
1259 | | callee-saved registers
1264 | | and incoming arguments
1271 stack pointer -> ----
1273 $SFP and $AP are used to represent frame pointer and arguments pointer,
1274 which will be both eliminated as hard frame pointer. */
1276 /* -- Eliminating Frame Pointer and Arg Pointer. */
1279 nds32_can_eliminate (const int from_reg
, const int to_reg
)
1281 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1284 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1287 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1290 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1296 /* -- Passing Arguments in Registers. */
1299 nds32_function_arg (cumulative_args_t ca
, enum machine_mode mode
,
1300 const_tree type
, bool named
)
1303 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1305 /* The last time this hook is called,
1306 it is called with MODE == VOIDmode. */
1307 if (mode
== VOIDmode
)
1310 /* For nameless arguments, we need to take care it individually. */
1313 /* If we are under hard float abi, we have arguments passed on the
1314 stack and all situation can be handled by GCC itself. */
1315 if (TARGET_HARD_FLOAT
)
1318 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1320 /* If we still have enough registers to pass argument, pick up
1321 next available register number. */
1323 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1324 return gen_rtx_REG (mode
, regno
);
1327 /* No register available, return NULL_RTX.
1328 The compiler will use stack to pass argument instead. */
1332 /* The following is to handle named argument.
1333 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1335 if (TARGET_HARD_FLOAT
)
1337 /* Currently we have not implemented hard float yet. */
1342 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1343 argument. Since we allow to pass argument partially in registers,
1344 we can just return it if there are still registers available. */
1345 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1347 /* Pick up the next available register number. */
1349 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1350 return gen_rtx_REG (mode
, regno
);
1355 /* No register available, return NULL_RTX.
1356 The compiler will use stack to pass argument instead. */
1361 nds32_must_pass_in_stack (enum machine_mode mode
, const_tree type
)
1363 /* Return true if a type must be passed in memory.
1364 If it is NOT using hard float abi, small aggregates can be
1365 passed in a register even we are calling a variadic function.
1366 So there is no need to take padding into consideration. */
1367 if (TARGET_HARD_FLOAT
)
1368 return must_pass_in_stack_var_size_or_pad (mode
, type
);
1370 return must_pass_in_stack_var_size (mode
, type
);
1374 nds32_arg_partial_bytes (cumulative_args_t ca
, enum machine_mode mode
,
1375 tree type
, bool named ATTRIBUTE_UNUSED
)
1377 /* Returns the number of bytes at the beginning of an argument that
1378 must be put in registers. The value must be zero for arguments that are
1379 passed entirely in registers or that are entirely pushed on the stack.
1380 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1381 first register to be used by the caller for this argument. */
1382 unsigned int needed_reg_count
;
1383 unsigned int remaining_reg_count
;
1384 CUMULATIVE_ARGS
*cum
;
1386 cum
= get_cumulative_args (ca
);
1388 /* Under hard float abi, we better have argument entirely passed in
1389 registers or pushed on the stack so that we can reduce the complexity
1390 of dealing with cum->gpr_offset and cum->fpr_offset. */
1391 if (TARGET_HARD_FLOAT
)
1394 /* If we have already runned out of argument registers, return zero
1395 so that the argument will be entirely pushed on the stack. */
1396 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1397 >= NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
)
1400 /* Calculate how many registers do we need for this argument. */
1401 needed_reg_count
= NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1403 /* Calculate how many argument registers have left for passing argument.
1404 Note that we should count it from next available register number. */
1406 = NDS32_MAX_GPR_REGS_FOR_ARGS
1407 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1408 - NDS32_GPR_ARG_FIRST_REGNUM
);
1410 /* Note that we have to return the nubmer of bytes, not registers count. */
1411 if (needed_reg_count
> remaining_reg_count
)
1412 return remaining_reg_count
* UNITS_PER_WORD
;
1418 nds32_function_arg_advance (cumulative_args_t ca
, enum machine_mode mode
,
1419 const_tree type
, bool named
)
1421 enum machine_mode sub_mode
;
1422 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1426 /* We need to further check TYPE and MODE so that we can determine
1427 which kind of register we shall advance. */
1428 if (type
&& TREE_CODE (type
) == COMPLEX_TYPE
)
1429 sub_mode
= TYPE_MODE (TREE_TYPE (type
));
1433 /* Under hard float abi, we may advance FPR registers. */
1434 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (sub_mode
) == MODE_FLOAT
)
1436 /* Currently we have not implemented hard float yet. */
1442 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1443 - NDS32_GPR_ARG_FIRST_REGNUM
1444 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1449 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1450 we can advance next register as well so that caller is
1451 able to pass arguments in registers and callee must be
1452 in charge of pushing all of them into stack. */
1453 if (!TARGET_HARD_FLOAT
)
1456 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1457 - NDS32_GPR_ARG_FIRST_REGNUM
1458 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1464 nds32_function_arg_boundary (enum machine_mode mode
, const_tree type
)
1466 return (nds32_needs_double_word_align (mode
, type
)
1467 ? NDS32_DOUBLE_WORD_ALIGNMENT
1471 /* -- How Scalar Function Values Are Returned. */
1474 nds32_function_value (const_tree ret_type
,
1475 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1476 bool outgoing ATTRIBUTE_UNUSED
)
1478 enum machine_mode mode
;
1481 mode
= TYPE_MODE (ret_type
);
1482 unsignedp
= TYPE_UNSIGNED (ret_type
);
1484 mode
= promote_mode (ret_type
, mode
, &unsignedp
);
1486 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
1490 nds32_libcall_value (enum machine_mode mode
,
1491 const_rtx fun ATTRIBUTE_UNUSED
)
1493 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
1497 nds32_function_value_regno_p (const unsigned int regno
)
1499 return (regno
== NDS32_GPR_RET_FIRST_REGNUM
);
1502 /* -- Function Entry and Exit. */
1504 /* The content produced from this function
1505 will be placed before prologue body. */
1507 nds32_asm_function_prologue (FILE *file
,
1508 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1511 const char *func_name
;
1515 /* All stack frame information is supposed to be
1516 already computed when expanding prologue.
1517 The result is in cfun->machine.
1518 DO NOT call nds32_compute_stack_frame() here
1519 because it may corrupt the essential information. */
1521 fprintf (file
, "\t! BEGIN PROLOGUE\n");
1522 fprintf (file
, "\t! fp needed: %d\n", frame_pointer_needed
);
1523 fprintf (file
, "\t! pretend_args: %d\n", cfun
->machine
->va_args_size
);
1524 fprintf (file
, "\t! local_size: %d\n", cfun
->machine
->local_size
);
1525 fprintf (file
, "\t! out_args_size: %d\n", cfun
->machine
->out_args_size
);
1527 /* Use df_regs_ever_live_p() to detect if the register
1528 is ever used in the current function. */
1529 fprintf (file
, "\t! registers ever_live: ");
1530 for (r
= 0; r
< 32; r
++)
1532 if (df_regs_ever_live_p (r
))
1533 fprintf (file
, "%s, ", reg_names
[r
]);
1537 /* Display the attributes of this function. */
1538 fprintf (file
, "\t! function attributes: ");
1539 /* Get the attributes tree list.
1540 Note that GCC builds attributes list with reverse order. */
1541 attrs
= DECL_ATTRIBUTES (current_function_decl
);
1543 /* If there is no any attribute, print out "None". */
1545 fprintf (file
, "None");
1547 /* If there are some attributes, try if we need to
1548 construct isr vector information. */
1549 func_name
= IDENTIFIER_POINTER (DECL_NAME (current_function_decl
));
1550 nds32_construct_isr_vectors_information (attrs
, func_name
);
1552 /* Display all attributes of this function. */
1555 name
= TREE_PURPOSE (attrs
);
1556 fprintf (file
, "%s ", IDENTIFIER_POINTER (name
));
1558 /* Pick up the next attribute. */
1559 attrs
= TREE_CHAIN (attrs
);
1564 /* After rtl prologue has been expanded, this function is used. */
1566 nds32_asm_function_end_prologue (FILE *file
)
1568 fprintf (file
, "\t! END PROLOGUE\n");
1570 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1571 we can generate special directive: ".omit_fp_begin"
1572 to guide linker doing fp-as-gp optimization.
1573 However, for a naked function, which means
1574 it should not have prologue/epilogue,
1575 using fp-as-gp still requires saving $fp by push/pop behavior and
1576 there is no benefit to use fp-as-gp on such small function.
1577 So we need to make sure this function is NOT naked as well. */
1578 if (!frame_pointer_needed
1579 && !cfun
->machine
->naked_p
1580 && cfun
->machine
->fp_as_gp_p
)
1582 fprintf (file
, "\t! ----------------------------------------\n");
1583 fprintf (file
, "\t! Guide linker to do "
1584 "link time optimization: fp-as-gp\n");
1585 fprintf (file
, "\t! We add one more instruction to "
1586 "initialize $fp near to $gp location.\n");
1587 fprintf (file
, "\t! If linker fails to use fp-as-gp transformation,\n");
1588 fprintf (file
, "\t! this extra instruction should be "
1589 "eliminated at link stage.\n");
1590 fprintf (file
, "\t.omit_fp_begin\n");
1591 fprintf (file
, "\tla\t$fp,_FP_BASE_\n");
1592 fprintf (file
, "\t! ----------------------------------------\n");
1596 /* Before rtl epilogue has been expanded, this function is used. */
1598 nds32_asm_function_begin_epilogue (FILE *file
)
1600 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1601 we can generate special directive: ".omit_fp_end"
1602 to claim fp-as-gp optimization range.
1603 However, for a naked function,
1604 which means it should not have prologue/epilogue,
1605 using fp-as-gp still requires saving $fp by push/pop behavior and
1606 there is no benefit to use fp-as-gp on such small function.
1607 So we need to make sure this function is NOT naked as well. */
1608 if (!frame_pointer_needed
1609 && !cfun
->machine
->naked_p
1610 && cfun
->machine
->fp_as_gp_p
)
1612 fprintf (file
, "\t! ----------------------------------------\n");
1613 fprintf (file
, "\t! Claim the range of fp-as-gp "
1614 "link time optimization\n");
1615 fprintf (file
, "\t.omit_fp_end\n");
1616 fprintf (file
, "\t! ----------------------------------------\n");
1619 fprintf (file
, "\t! BEGIN EPILOGUE\n");
1622 /* The content produced from this function
1623 will be placed after epilogue body. */
1625 nds32_asm_function_epilogue (FILE *file
,
1626 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
1628 fprintf (file
, "\t! END EPILOGUE\n");
1632 nds32_asm_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
1633 HOST_WIDE_INT delta
,
1634 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
1639 /* Make sure unwind info is emitted for the thunk if needed. */
1640 final_start_function (emit_barrier (), file
, 1);
1642 this_regno
= (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
)
1648 if (satisfies_constraint_Is15 (GEN_INT (delta
)))
1650 fprintf (file
, "\taddi\t$r%d, $r%d, %ld\n",
1651 this_regno
, this_regno
, delta
);
1653 else if (satisfies_constraint_Is20 (GEN_INT (delta
)))
1655 fprintf (file
, "\tmovi\t$ta, %ld\n", delta
);
1656 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
1660 fprintf (file
, "\tsethi\t$ta, hi20(%ld)\n", delta
);
1661 fprintf (file
, "\tori\t$ta, $ta, lo12(%ld)\n", delta
);
1662 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
1666 fprintf (file
, "\tb\t");
1667 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
1668 fprintf (file
, "\n");
1670 final_end_function ();
1673 /* -- Permitting tail calls. */
1675 /* Determine whether we need to enable warning for function return check. */
1677 nds32_warn_func_return (tree decl
)
1679 /* Naked functions are implemented entirely in assembly, including the
1680 return sequence, so suppress warnings about this. */
1681 return !nds32_naked_function_p (decl
);
1685 /* Implementing the Varargs Macros. */
1688 nds32_setup_incoming_varargs (cumulative_args_t ca
,
1689 enum machine_mode mode
,
1691 int *pretend_args_size
,
1692 int second_time ATTRIBUTE_UNUSED
)
1694 unsigned int total_args_regs
;
1695 unsigned int num_of_used_regs
;
1696 unsigned int remaining_reg_count
;
1697 CUMULATIVE_ARGS
*cum
;
1699 /* If we are under hard float abi, we do not need to set *pretend_args_size.
1700 So that all nameless arguments are pushed by caller and all situation
1701 can be handled by GCC itself. */
1702 if (TARGET_HARD_FLOAT
)
1705 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
1706 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
1707 However, for nameless(anonymous) arguments, we should push them on the
1708 stack so that all the nameless arguments appear to have been passed
1709 consecutively in the memory for accessing. Hence, we need to check and
1710 exclude the registers that are used for named arguments. */
1712 cum
= get_cumulative_args (ca
);
1714 /* The MODE and TYPE describe the last argument.
1715 We need those information to determine the remaining registers
1718 = NDS32_MAX_GPR_REGS_FOR_ARGS
+ NDS32_GPR_ARG_FIRST_REGNUM
;
1720 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1721 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1723 remaining_reg_count
= total_args_regs
- num_of_used_regs
;
1724 *pretend_args_size
= remaining_reg_count
* UNITS_PER_WORD
;
1730 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
1732 /* If this hook returns true, the named argument of FUNCTION_ARG is always
1733 true for named arguments, and false for unnamed arguments. */
1738 /* Trampolines for Nested Functions. */
1741 nds32_asm_trampoline_template (FILE *f
)
1743 if (TARGET_REDUCED_REGS
)
1745 /* Trampoline is not supported on reduced-set registers yet. */
1746 sorry ("a nested function is not supported for reduced registers");
1750 asm_fprintf (f
, "\t! Trampoline code template\n");
1751 asm_fprintf (f
, "\t! This code fragment will be copied "
1752 "into stack on demand\n");
1754 asm_fprintf (f
, "\tmfusr\t$r16,$pc\n");
1755 asm_fprintf (f
, "\tlwi\t$r15,[$r16 + 20] "
1756 "! load nested function address\n");
1757 asm_fprintf (f
, "\tlwi\t$r16,[$r16 + 16] "
1758 "! load chain_value\n");
1759 asm_fprintf (f
, "\tjr\t$r15\n");
1762 /* Preserve space ($pc + 16) for saving chain_value,
1763 nds32_trampoline_init will fill the value in this slot. */
1764 asm_fprintf (f
, "\t! space for saving chain_value\n");
1765 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
1767 /* Preserve space ($pc + 20) for saving nested function address,
1768 nds32_trampoline_init will fill the value in this slot. */
1769 asm_fprintf (f
, "\t! space for saving nested function address\n");
1770 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
1773 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1775 nds32_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
1779 /* Nested function address. */
1781 /* The memory rtx that is going to
1782 be filled with chain_value. */
1783 rtx chain_value_mem
;
1784 /* The memory rtx that is going to
1785 be filled with nested function address. */
1786 rtx nested_func_mem
;
1788 /* Start address of trampoline code in stack, for doing cache sync. */
1789 rtx sync_cache_addr
;
1790 /* Temporary register for sync instruction. */
1792 /* Instruction-cache sync instruction,
1793 requesting an argument as starting address. */
1795 /* For convenience reason of doing comparison. */
1796 int tramp_align_in_bytes
;
1798 /* Trampoline is not supported on reduced-set registers yet. */
1799 if (TARGET_REDUCED_REGS
)
1800 sorry ("a nested function is not supported for reduced registers");
1802 /* STEP 1: Copy trampoline code template into stack,
1803 fill up essential data into stack. */
1805 /* Extract nested function address rtx. */
1806 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
1808 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1809 We have nds32_asm_trampoline_template() to emit template pattern. */
1810 emit_block_move (m_tramp
, assemble_trampoline_template (),
1811 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
1813 /* After copying trampoline code into stack,
1814 fill chain_value into stack. */
1815 chain_value_mem
= adjust_address (m_tramp
, SImode
, 16);
1816 emit_move_insn (chain_value_mem
, chain_value
);
1817 /* After copying trampoline code int stack,
1818 fill nested function address into stack. */
1819 nested_func_mem
= adjust_address (m_tramp
, SImode
, 20);
1820 emit_move_insn (nested_func_mem
, fnaddr
);
1822 /* STEP 2: Sync instruction-cache. */
1824 /* We have successfully filled trampoline code into stack.
1825 However, in order to execute code in stack correctly,
1826 we must sync instruction cache. */
1827 sync_cache_addr
= XEXP (m_tramp
, 0);
1828 tmp_reg
= gen_reg_rtx (SImode
);
1829 isync_insn
= gen_unspec_volatile_isync (tmp_reg
);
1831 /* Because nds32_cache_block_size is in bytes,
1832 we get trampoline alignment in bytes for convenient comparison. */
1833 tramp_align_in_bytes
= TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
;
1835 if (tramp_align_in_bytes
>= nds32_cache_block_size
1836 && (tramp_align_in_bytes
% nds32_cache_block_size
) == 0)
1838 /* Under this condition, the starting address of trampoline
1839 must be aligned to the starting address of each cache block
1840 and we do not have to worry about cross-boundary issue. */
1842 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
1843 / nds32_cache_block_size
;
1846 emit_move_insn (tmp_reg
,
1847 plus_constant (Pmode
, sync_cache_addr
,
1848 nds32_cache_block_size
* i
));
1849 emit_insn (isync_insn
);
1852 else if (TRAMPOLINE_SIZE
> nds32_cache_block_size
)
1854 /* The starting address of trampoline code
1855 may not be aligned to the cache block,
1856 so the trampoline code may be across two cache block.
1857 We need to sync the last element, which is 4-byte size,
1858 of trampoline template. */
1860 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
1861 / nds32_cache_block_size
;
1864 emit_move_insn (tmp_reg
,
1865 plus_constant (Pmode
, sync_cache_addr
,
1866 nds32_cache_block_size
* i
));
1867 emit_insn (isync_insn
);
1870 /* The last element of trampoline template is 4-byte size. */
1871 emit_move_insn (tmp_reg
,
1872 plus_constant (Pmode
, sync_cache_addr
,
1873 TRAMPOLINE_SIZE
- 4));
1874 emit_insn (isync_insn
);
1878 /* This is the simplest case.
1879 Because TRAMPOLINE_SIZE is less than or
1880 equal to nds32_cache_block_size,
1881 we can just sync start address and
1882 the last element of trampoline code. */
1884 /* Sync starting address of tampoline code. */
1885 emit_move_insn (tmp_reg
, sync_cache_addr
);
1886 emit_insn (isync_insn
);
1887 /* Sync the last element, which is 4-byte size,
1888 of trampoline template. */
1889 emit_move_insn (tmp_reg
,
1890 plus_constant (Pmode
, sync_cache_addr
,
1891 TRAMPOLINE_SIZE
- 4));
1892 emit_insn (isync_insn
);
1895 /* Set instruction serialization barrier
1896 to guarantee the correct operations. */
1897 emit_insn (gen_unspec_volatile_isb ());
1901 /* Addressing Modes. */
1904 nds32_legitimate_address_p (enum machine_mode mode
, rtx x
, bool strict
)
1906 /* For (mem:DI addr) or (mem:DF addr) case,
1907 we only allow 'addr' to be [reg], [symbol_ref],
1908 [const], or [reg + const_int] pattern. */
1909 if (mode
== DImode
|| mode
== DFmode
)
1911 /* Allow [Reg + const_int] addressing mode. */
1912 if (GET_CODE (x
) == PLUS
)
1914 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
1915 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
)
1916 && CONST_INT_P (XEXP (x
, 1)))
1919 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
1920 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
)
1921 && CONST_INT_P (XEXP (x
, 0)))
1925 /* Now check [reg], [symbol_ref], and [const]. */
1926 if (GET_CODE (x
) != REG
1927 && GET_CODE (x
) != SYMBOL_REF
1928 && GET_CODE (x
) != CONST
)
1932 /* Check if 'x' is a valid address. */
1933 switch (GET_CODE (x
))
1936 /* (mem (reg A)) => [Ra] */
1937 return nds32_address_register_rtx_p (x
, strict
);
1941 if (!TARGET_GP_DIRECT
1942 && (reload_completed
1943 || reload_in_progress
1944 || lra_in_progress
))
1947 /* (mem (symbol_ref A)) => [symbol_ref] */
1948 return !currently_expanding_to_rtl
;
1952 if (!TARGET_GP_DIRECT
1953 && (reload_completed
1954 || reload_in_progress
1955 || lra_in_progress
))
1958 /* (mem (const (...)))
1959 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1960 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
1962 rtx plus_op
= XEXP (x
, 0);
1964 rtx op0
= XEXP (plus_op
, 0);
1965 rtx op1
= XEXP (plus_op
, 1);
1967 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
1976 /* (mem (post_modify (reg) (plus (reg) (reg))))
1978 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1979 => [Ra], const_int */
1980 if (GET_CODE (XEXP (x
, 0)) == REG
1981 && GET_CODE (XEXP (x
, 1)) == PLUS
)
1983 rtx plus_op
= XEXP (x
, 1);
1985 rtx op0
= XEXP (plus_op
, 0);
1986 rtx op1
= XEXP (plus_op
, 1);
1988 if (nds32_address_register_rtx_p (op0
, strict
)
1989 && nds32_legitimate_index_p (mode
, op1
, strict
))
1999 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2000 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2001 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2002 We only need to deal with register Ra. */
2003 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2009 /* (mem (plus reg const_int))
2011 /* (mem (plus reg reg))
2013 /* (mem (plus (mult reg const_int) reg))
2014 => [Ra + Rb << sv] */
2015 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2016 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
))
2018 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2019 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
))
2025 if (!TARGET_GP_DIRECT
)
2034 /* Describing Relative Costs of Operations. */
2037 nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED
,
2041 if (from
== HIGH_REGS
|| to
== HIGH_REGS
)
2048 nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED
,
2049 reg_class_t rclass ATTRIBUTE_UNUSED
,
2050 bool in ATTRIBUTE_UNUSED
)
2055 /* This target hook describes the relative costs of RTL expressions.
2056 Return 'true' when all subexpressions of x have been processed.
2057 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2058 Refer to gcc/rtlanal.c for more information. */
2060 nds32_rtx_costs (rtx x
,
2067 return nds32_rtx_costs_impl (x
, code
, outer_code
, opno
, total
, speed
);
2071 nds32_address_cost (rtx address
,
2072 enum machine_mode mode
,
2076 return nds32_address_cost_impl (address
, mode
, as
, speed
);
2080 /* Defining the Output Assembler Language. */
2082 /* -- The Overall Framework of an Assembler File. */
2085 nds32_asm_file_start (void)
2087 default_file_start ();
2089 /* Tell assembler which ABI we are using. */
2090 fprintf (asm_out_file
, "\t! ABI version\n");
2091 fprintf (asm_out_file
, "\t.abi_2\n");
2093 /* Tell assembler that this asm code is generated by compiler. */
2094 fprintf (asm_out_file
, "\t! This asm file is generated by compiler\n");
2095 fprintf (asm_out_file
, "\t.flag\tverbatim\n");
2096 /* Give assembler the size of each vector for interrupt handler. */
2097 fprintf (asm_out_file
, "\t! This vector size directive is required "
2098 "for checking inconsistency on interrupt handler\n");
2099 fprintf (asm_out_file
, "\t.vec_size\t%d\n", nds32_isr_vector_size
);
2101 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
2102 the compiler may produce 'la $fp,_FP_BASE_' instruction
2103 at prologue for fp-as-gp optimization.
2104 We should emit weak reference of _FP_BASE_ to avoid undefined reference
2105 in case user does not pass '--relax' option to linker. */
2106 if (TARGET_FORCE_FP_AS_GP
|| optimize_size
)
2108 fprintf (asm_out_file
, "\t! This weak reference is required to do "
2109 "fp-as-gp link time optimization\n");
2110 fprintf (asm_out_file
, "\t.weak\t_FP_BASE_\n");
2112 /* If user enables '-mex9', we should emit relaxation directive
2113 to tell linker that this file is allowed to do ex9 optimization. */
2116 fprintf (asm_out_file
, "\t! This relaxation directive is required "
2117 "to do ex9 link time optimization\n");
2118 fprintf (asm_out_file
, "\t.relax\tex9\n");
2121 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2124 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V2");
2126 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3");
2128 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3M");
2130 fprintf (asm_out_file
, "\t! Endian setting\t: %s\n",
2131 ((TARGET_BIG_ENDIAN
) ? "big-endian"
2132 : "little-endian"));
2134 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2136 fprintf (asm_out_file
, "\t! Use conditional move\t\t: %s\n",
2137 ((TARGET_CMOV
) ? "Yes"
2139 fprintf (asm_out_file
, "\t! Use performance extension\t: %s\n",
2140 ((TARGET_PERF_EXT
) ? "Yes"
2143 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2145 fprintf (asm_out_file
, "\t! V3PUSH instructions\t: %s\n",
2146 ((TARGET_V3PUSH
) ? "Yes"
2148 fprintf (asm_out_file
, "\t! 16-bit instructions\t: %s\n",
2149 ((TARGET_16_BIT
) ? "Yes"
2151 fprintf (asm_out_file
, "\t! GP base access\t: %s\n",
2152 ((TARGET_GP_DIRECT
) ? "Yes"
2154 fprintf (asm_out_file
, "\t! Reduced registers set\t: %s\n",
2155 ((TARGET_REDUCED_REGS
) ? "Yes"
2158 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2161 fprintf (asm_out_file
, "\t! Optimization level\t: -Os\n");
2163 fprintf (asm_out_file
, "\t! Optimization level\t: -O%d\n", optimize
);
2165 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2167 fprintf (asm_out_file
, "\t! Cache block size\t: %d\n",
2168 nds32_cache_block_size
);
2170 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2172 nds32_asm_file_start_for_isr ();
2176 nds32_asm_file_end (void)
2178 nds32_asm_file_end_for_isr ();
2180 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2183 /* -- Output and Generation of Labels. */
2186 nds32_asm_globalize_label (FILE *stream
, const char *name
)
2188 fputs ("\t.global\t", stream
);
2189 assemble_name (stream
, name
);
2190 fputs ("\n", stream
);
2193 /* -- Output of Assembler Instructions. */
2196 nds32_print_operand (FILE *stream
, rtx x
, int code
)
2203 /* Do nothing special. */
2207 /* 'x' is supposed to be CONST_INT, get the value. */
2208 gcc_assert (CONST_INT_P (x
));
2209 op_value
= INTVAL (x
);
2211 /* According to the Andes architecture,
2212 the system/user register index range is 0 ~ 1023.
2213 In order to avoid conflict between user-specified-integer value
2214 and enum-specified-register value,
2215 the 'enum nds32_intrinsic_registers' value
2216 in nds32_intrinsic.h starts from 1024. */
2217 if (op_value
< 1024 && op_value
>= 0)
2219 /* If user gives integer value directly (0~1023),
2220 we just print out the value. */
2221 fprintf (stream
, "%d", op_value
);
2223 else if (op_value
< 0
2224 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
2227 /* The enum index value for array size is out of range. */
2228 error ("intrinsic register index is out of range");
2232 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2233 we can print out register name. Remember to substract 1024. */
2234 fprintf (stream
, "%s",
2235 nds32_intrinsic_register_names
[op_value
- 1024]);
2238 /* No need to handle following process, so return immediately. */
2243 output_operand_lossage ("invalid operand output code");
2247 switch (GET_CODE (x
))
2251 output_addr_const (stream
, x
);
2255 /* Forbid using static chain register ($r16)
2256 on reduced-set registers configuration. */
2257 if (TARGET_REDUCED_REGS
2258 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
2259 sorry ("a nested function is not supported for reduced registers");
2261 /* Normal cases, print out register name. */
2262 fputs (reg_names
[REGNO (x
)], stream
);
2266 output_address (XEXP (x
, 0));
2272 output_addr_const (stream
, x
);
2276 /* Generally, output_addr_const () is able to handle most cases.
2277 We want to see what CODE could appear,
2278 so we use gcc_unreachable() to stop it. */
2286 nds32_print_operand_address (FILE *stream
, rtx x
)
2290 switch (GET_CODE (x
))
2294 /* [ + symbol_ref] */
2295 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2296 fputs ("[ + ", stream
);
2297 output_addr_const (stream
, x
);
2298 fputs ("]", stream
);
2302 /* Forbid using static chain register ($r16)
2303 on reduced-set registers configuration. */
2304 if (TARGET_REDUCED_REGS
2305 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
2306 sorry ("a nested function is not supported for reduced registers");
2309 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
2316 /* Checking op0, forbid using static chain register ($r16)
2317 on reduced-set registers configuration. */
2318 if (TARGET_REDUCED_REGS
2320 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2321 sorry ("a nested function is not supported for reduced registers");
2322 /* Checking op1, forbid using static chain register ($r16)
2323 on reduced-set registers configuration. */
2324 if (TARGET_REDUCED_REGS
2326 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
2327 sorry ("a nested function is not supported for reduced registers");
2329 if (REG_P (op0
) && CONST_INT_P (op1
))
2332 fprintf (stream
, "[%s + (%d)]",
2333 reg_names
[REGNO (op0
)], (int)INTVAL (op1
));
2335 else if (REG_P (op0
) && REG_P (op1
))
2338 fprintf (stream
, "[%s + %s]",
2339 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
2341 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
2344 From observation, the pattern looks like:
2345 (plus:SI (mult:SI (reg:SI 58)
2346 (const_int 4 [0x4]))
2350 /* We need to set sv to output shift value. */
2351 if (INTVAL (XEXP (op0
, 1)) == 1)
2353 else if (INTVAL (XEXP (op0
, 1)) == 2)
2355 else if (INTVAL (XEXP (op0
, 1)) == 4)
2360 fprintf (stream
, "[%s + %s << %d]",
2361 reg_names
[REGNO (op1
)],
2362 reg_names
[REGNO (XEXP (op0
, 0))],
2367 /* The control flow is not supposed to be here. */
2375 /* (post_modify (regA) (plus (regA) (regB)))
2376 (post_modify (regA) (plus (regA) (const_int)))
2377 We would like to extract
2378 regA and regB (or const_int) from plus rtx. */
2379 op0
= XEXP (XEXP (x
, 1), 0);
2380 op1
= XEXP (XEXP (x
, 1), 1);
2382 /* Checking op0, forbid using static chain register ($r16)
2383 on reduced-set registers configuration. */
2384 if (TARGET_REDUCED_REGS
2386 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2387 sorry ("a nested function is not supported for reduced registers");
2388 /* Checking op1, forbid using static chain register ($r16)
2389 on reduced-set registers configuration. */
2390 if (TARGET_REDUCED_REGS
2392 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
2393 sorry ("a nested function is not supported for reduced registers");
2395 if (REG_P (op0
) && REG_P (op1
))
2398 fprintf (stream
, "[%s], %s",
2399 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
2401 else if (REG_P (op0
) && CONST_INT_P (op1
))
2404 fprintf (stream
, "[%s], %d",
2405 reg_names
[REGNO (op0
)], (int)INTVAL (op1
));
2409 /* The control flow is not supposed to be here. */
2420 /* Checking op0, forbid using static chain register ($r16)
2421 on reduced-set registers configuration. */
2422 if (TARGET_REDUCED_REGS
2424 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
2425 sorry ("a nested function is not supported for reduced registers");
2429 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2430 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2431 We only need to deal with register Ra. */
2432 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
2436 /* The control flow is not supposed to be here. */
2444 /* Generally, output_addr_const () is able to handle most cases.
2445 We want to see what CODE could appear,
2446 so we use gcc_unreachable() to stop it. */
2454 /* Defining target-specific uses of __attribute__. */
2456 /* Add some checking after merging attributes. */
2458 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
2460 tree combined_attrs
;
2462 /* Create combined attributes. */
2463 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
2464 DECL_ATTRIBUTES (newdecl
));
2466 /* Since newdecl is acutally a duplicate of olddecl,
2467 we can take olddecl for some operations. */
2468 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
2470 /* Check isr-specific attributes conflict. */
2471 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
2474 return combined_attrs
;
2477 /* Add some checking when inserting attributes. */
2479 nds32_insert_attributes (tree decl
, tree
*attributes
)
2481 /* For function declaration, we need to check isr-specific attributes:
2482 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2483 2. Check valid integer value for interrupt/exception.
2484 3. Check valid integer value for reset.
2485 4. Check valid function for nmi/warm. */
2486 if (TREE_CODE (decl
) == FUNCTION_DECL
)
2489 tree intr
, excp
, reset
;
2491 /* Pick up function attributes. */
2492 func_attrs
= *attributes
;
2494 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2495 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
2497 /* Now we are starting to check valid id value
2498 for interrupt/exception/reset.
2499 Note that we ONLY check its validity here.
2500 To construct isr vector information, it is still performed
2501 by nds32_construct_isr_vectors_information(). */
2502 intr
= lookup_attribute ("interrupt", func_attrs
);
2503 excp
= lookup_attribute ("exception", func_attrs
);
2504 reset
= lookup_attribute ("reset", func_attrs
);
2508 /* Deal with interrupt/exception. */
2510 unsigned int lower_bound
, upper_bound
;
2512 /* The way to handle interrupt or exception is the same,
2513 we just need to take care of actual vector number.
2514 For interrupt(0..63), the actual vector number is (9..72).
2515 For exception(1..8), the actual vector number is (1..8). */
2516 lower_bound
= (intr
) ? (0) : (1);
2517 upper_bound
= (intr
) ? (63) : (8);
2519 /* Prepare id list so that we can traverse id value. */
2520 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
2522 /* 2. Check valid integer value for interrupt/exception. */
2527 /* Pick up each vector id value. */
2528 id
= TREE_VALUE (id_list
);
2529 /* Issue error if it is not a valid integer value. */
2530 if (TREE_CODE (id
) != INTEGER_CST
2531 || wi::ltu_p (id
, lower_bound
)
2532 || wi::gtu_p (id
, upper_bound
))
2533 error ("invalid id value for interrupt/exception attribute");
2535 /* Advance to next id. */
2536 id_list
= TREE_CHAIN (id_list
);
2541 /* Deal with reset. */
2545 unsigned int lower_bound
;
2546 unsigned int upper_bound
;
2548 /* Prepare id_list and identify id value so that
2549 we can check if total number of vectors is valid. */
2550 id_list
= TREE_VALUE (reset
);
2551 id
= TREE_VALUE (id_list
);
2553 /* The maximum numbers for user's interrupt is 64. */
2557 /* 3. Check valid integer value for reset. */
2558 if (TREE_CODE (id
) != INTEGER_CST
2559 || wi::ltu_p (id
, lower_bound
)
2560 || wi::gtu_p (id
, upper_bound
))
2561 error ("invalid id value for reset attribute");
2563 /* 4. Check valid function for nmi/warm. */
2564 nmi
= lookup_attribute ("nmi", func_attrs
);
2565 warm
= lookup_attribute ("warm", func_attrs
);
2567 if (nmi
!= NULL_TREE
)
2572 nmi_func_list
= TREE_VALUE (nmi
);
2573 nmi_func
= TREE_VALUE (nmi_func_list
);
2575 /* Issue error if it is not a valid nmi function. */
2576 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
2577 error ("invalid nmi function for reset attribute");
2580 if (warm
!= NULL_TREE
)
2582 tree warm_func_list
;
2585 warm_func_list
= TREE_VALUE (warm
);
2586 warm_func
= TREE_VALUE (warm_func_list
);
2588 /* Issue error if it is not a valid warm function. */
2589 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
2590 error ("invalid warm function for reset attribute");
2595 /* No interrupt, exception, or reset attribute is set. */
2602 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
2603 tree pop_target ATTRIBUTE_UNUSED
)
2605 /* Currently, we do not parse any pragma target by ourself,
2606 so just simply return false. */
2611 nds32_option_override (void)
2613 /* After all the command options have been parsed,
2614 we shall deal with some flags for changing compiler settings. */
2616 /* At first, we check if we have to strictly
2617 set some flags based on ISA family. */
2620 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2621 target_flags
&= ~MASK_V3PUSH
;
2625 /* Under V3 ISA, currently nothing should be strictly set. */
2629 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2630 target_flags
|= MASK_REDUCED_REGS
;
2631 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2632 target_flags
&= ~MASK_PERF_EXT
;
2635 /* See if we are using reduced-set registers:
2636 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2637 If so, we must forbid using $r11~$r14, $r16~$r27. */
2638 if (TARGET_REDUCED_REGS
)
2642 /* Prevent register allocator from
2643 choosing it as doing register allocation. */
2644 for (r
= 11; r
<= 14; r
++)
2645 fixed_regs
[r
] = call_used_regs
[r
] = 1;
2646 for (r
= 16; r
<= 27; r
++)
2647 fixed_regs
[r
] = call_used_regs
[r
] = 1;
2650 /* See if user explicitly would like to use fp-as-gp optimization.
2651 If so, we must prevent $fp from being allocated
2652 during register allocation. */
2653 if (TARGET_FORCE_FP_AS_GP
)
2654 fixed_regs
[FP_REGNUM
] = call_used_regs
[FP_REGNUM
] = 1;
2658 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2659 target_flags
&= ~MASK_V3PUSH
;
2662 /* Currently, we don't support PIC code generation yet. */
2664 sorry ("not support -fpic");
2668 /* Miscellaneous Parameters. */
2671 nds32_init_builtins (void)
2673 nds32_init_builtins_impl ();
2677 nds32_expand_builtin (tree exp
,
2680 enum machine_mode mode
,
2683 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
2687 /* ------------------------------------------------------------------------ */
2689 /* PART 4: Implemet extern function definitions,
2690 the prototype is in nds32-protos.h. */
2692 /* Defining Data Structures for Per-function Information. */
2695 nds32_init_expanders (void)
2697 /* Arrange to initialize and mark the machine per-function status. */
2698 init_machine_status
= nds32_init_machine_status
;
2702 /* Register Usage. */
2704 /* -- How Values Fit in Registers. */
2707 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED
,
2708 enum machine_mode mode
)
2710 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
2714 nds32_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
2716 /* Restrict double-word quantities to even register pairs. */
2717 if (HARD_REGNO_NREGS (regno
, mode
) == 1
2725 /* Register Classes. */
2728 nds32_regno_reg_class (int regno
)
2730 /* Refer to nds32.h for more register class details. */
2732 if (regno
>= 0 && regno
<= 7)
2734 else if (regno
>= 8 && regno
<= 11)
2736 else if (regno
>= 12 && regno
<= 14)
2738 else if (regno
== 15)
2740 else if (regno
>= 16 && regno
<= 19)
2742 else if (regno
>= 20 && regno
<= 31)
2744 else if (regno
== 32 || regno
== 33)
2751 /* Stack Layout and Calling Conventions. */
2753 /* -- Basic Stack Layout. */
2756 nds32_return_addr_rtx (int count
,
2757 rtx frameaddr ATTRIBUTE_UNUSED
)
2759 /* There is no way to determine the return address
2760 if frameaddr is the frame that has 'count' steps
2761 up from current frame. */
2765 /* If count == 0, it means we are at current frame,
2766 the return address is $r30 ($lp). */
2767 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
2770 /* -- Eliminating Frame Pointer and Arg Pointer. */
2773 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
2775 HOST_WIDE_INT offset
;
2777 /* Compute and setup stack frame size.
2778 The result will be in cfun->machine. */
2779 nds32_compute_stack_frame ();
2781 /* Remember to consider
2782 cfun->machine->callee_saved_area_padding_bytes
2783 when calculating offset. */
2784 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
2786 offset
= (cfun
->machine
->fp_size
2787 + cfun
->machine
->gp_size
2788 + cfun
->machine
->lp_size
2789 + cfun
->machine
->callee_saved_regs_size
2790 + cfun
->machine
->callee_saved_area_padding_bytes
2791 + cfun
->machine
->local_size
2792 + cfun
->machine
->out_args_size
);
2794 else if (from_reg
== ARG_POINTER_REGNUM
2795 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
2799 else if (from_reg
== FRAME_POINTER_REGNUM
2800 && to_reg
== STACK_POINTER_REGNUM
)
2802 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
2804 else if (from_reg
== FRAME_POINTER_REGNUM
2805 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
2807 offset
= (-1) * (cfun
->machine
->fp_size
2808 + cfun
->machine
->gp_size
2809 + cfun
->machine
->lp_size
2810 + cfun
->machine
->callee_saved_regs_size
2811 + cfun
->machine
->callee_saved_area_padding_bytes
);
2821 /* -- Passing Arguments in Registers. */
2824 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
2825 tree fntype ATTRIBUTE_UNUSED
,
2826 rtx libname ATTRIBUTE_UNUSED
,
2827 tree fndecl ATTRIBUTE_UNUSED
,
2828 int n_named_args ATTRIBUTE_UNUSED
)
2830 /* Initial available registers
2831 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2832 for passing arguments. */
2833 cum
->gpr_offset
= 0;
2836 /* -- Function Entry and Exit. */
2838 /* Function for normal multiple push prologue. */
2840 nds32_expand_prologue (void)
2847 rtx fp_adjust_insn
, sp_adjust_insn
;
2849 /* Compute and setup stack frame size.
2850 The result will be in cfun->machine. */
2851 nds32_compute_stack_frame ();
2853 /* If this is a variadic function, first we need to push argument
2854 registers that hold the unnamed argument value. */
2855 if (cfun
->machine
->va_args_size
!= 0)
2857 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->va_args_first_regno
);
2858 Re
= gen_rtx_REG (SImode
, cfun
->machine
->va_args_last_regno
);
2859 /* No need to push $fp, $gp, or $lp, so use GEN_INT(0). */
2860 nds32_emit_stack_push_multiple (Rb
, Re
, GEN_INT (0));
2862 /* We may also need to adjust stack pointer for padding bytes
2863 because varargs may cause $sp not 8-byte aligned. */
2864 if (cfun
->machine
->va_args_area_padding_bytes
)
2866 /* Generate sp adjustment instruction. */
2867 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
2868 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
2870 GEN_INT (-1 * sp_adjust
));
2872 /* Emit rtx into instructions list and receive INSN rtx form. */
2873 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
2875 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2876 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2877 generate CFI (Call Frame Information) stuff. */
2878 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
2882 /* If the function is 'naked',
2883 we do not have to generate prologue code fragment. */
2884 if (cfun
->machine
->naked_p
)
2887 /* Get callee_first_regno and callee_last_regno. */
2888 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_first_regno
);
2889 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_last_regno
);
2891 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2892 the pattern 'stack_push_multiple' is implemented in nds32.md.
2893 For En4 field, we have to calculate its constant value.
2894 Refer to Andes ISA for more information. */
2896 if (cfun
->machine
->fp_size
)
2898 if (cfun
->machine
->gp_size
)
2900 if (cfun
->machine
->lp_size
)
2903 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2904 to be saved, we don't have to create multiple push instruction.
2905 Otherwise, a multiple push instruction is needed. */
2906 if (!(REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
&& en4_const
== 0))
2908 /* Create multiple push instruction rtx. */
2909 nds32_emit_stack_push_multiple (Rb
, Re
, GEN_INT (en4_const
));
2912 /* Check frame_pointer_needed to see
2913 if we shall emit fp adjustment instruction. */
2914 if (frame_pointer_needed
)
2916 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2917 + (4 * callee-saved-registers)
2918 Note: No need to adjust
2919 cfun->machine->callee_saved_area_padding_bytes,
2920 because, at this point, stack pointer is just
2921 at the position after push instruction. */
2922 fp_adjust
= cfun
->machine
->fp_size
2923 + cfun
->machine
->gp_size
2924 + cfun
->machine
->lp_size
2925 + cfun
->machine
->callee_saved_regs_size
;
2926 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
2928 GEN_INT (fp_adjust
));
2929 /* Emit rtx into instructions list and receive INSN rtx form. */
2930 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
2933 /* Adjust $sp = $sp - local_size - out_args_size
2934 - callee_saved_area_padding_bytes. */
2935 sp_adjust
= cfun
->machine
->local_size
2936 + cfun
->machine
->out_args_size
2937 + cfun
->machine
->callee_saved_area_padding_bytes
;
2938 /* sp_adjust value may be out of range of the addi instruction,
2939 create alternative add behavior with TA_REGNUM if necessary,
2940 using NEGATIVE value to tell that we are decreasing address. */
2941 sp_adjust
= nds32_force_addi_stack_int ( (-1) * sp_adjust
);
2944 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2945 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
2947 GEN_INT (-1 * sp_adjust
));
2948 /* Emit rtx into instructions list and receive INSN rtx form. */
2949 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
2951 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2952 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2953 generate CFI (Call Frame Information) stuff. */
2954 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
2957 /* Prevent the instruction scheduler from
2958 moving instructions across the boundary. */
2959 emit_insn (gen_blockage ());
2962 /* Function for normal multiple pop epilogue. */
2964 nds32_expand_epilogue (void)
2972 /* Compute and setup stack frame size.
2973 The result will be in cfun->machine. */
2974 nds32_compute_stack_frame ();
2976 /* Prevent the instruction scheduler from
2977 moving instructions across the boundary. */
2978 emit_insn (gen_blockage ());
2980 /* If the function is 'naked', we do not have to generate
2981 epilogue code fragment BUT 'ret' instruction.
2982 However, if this function is also a variadic function,
2983 we need to create adjust stack pointer before 'ret' instruction. */
2984 if (cfun
->machine
->naked_p
)
2986 /* If this is a variadic function, we do not have to restore argument
2987 registers but need to adjust stack pointer back to previous stack
2988 frame location before return. */
2989 if (cfun
->machine
->va_args_size
!= 0)
2991 /* Generate sp adjustment instruction.
2992 We need to consider padding bytes here. */
2993 sp_adjust
= cfun
->machine
->va_args_size
2994 + cfun
->machine
->va_args_area_padding_bytes
;
2995 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
2997 GEN_INT (sp_adjust
));
2998 /* Emit rtx into instructions list and receive INSN rtx form. */
2999 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3001 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3002 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3003 generate CFI (Call Frame Information) stuff. */
3004 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3007 /* Generate return instruction by using
3008 unspec_volatile_func_return pattern.
3009 Make sure this instruction is after gen_blockage().
3010 NOTE that $lp will become 'live'
3011 after this instruction has been emitted. */
3012 emit_insn (gen_unspec_volatile_func_return ());
3016 if (frame_pointer_needed
)
3018 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
3019 - (4 * callee-saved-registers)
3020 Note: No need to adjust
3021 cfun->machine->callee_saved_area_padding_bytes,
3022 because we want to adjust stack pointer
3023 to the position for pop instruction. */
3024 sp_adjust
= cfun
->machine
->fp_size
3025 + cfun
->machine
->gp_size
3026 + cfun
->machine
->lp_size
3027 + cfun
->machine
->callee_saved_regs_size
;
3028 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3029 hard_frame_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 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3039 /* If frame pointer is NOT needed,
3040 we cannot calculate the sp adjustment from frame pointer.
3041 Instead, we calculate the adjustment by local_size,
3042 out_args_size, and callee_saved_area_padding_bytes.
3043 Notice that such sp adjustment value may be out of range,
3044 so we have to deal with it as well. */
3046 /* Adjust $sp = $sp + local_size + out_args_size
3047 + callee_saved_area_padding_bytes. */
3048 sp_adjust
= cfun
->machine
->local_size
3049 + cfun
->machine
->out_args_size
3050 + cfun
->machine
->callee_saved_area_padding_bytes
;
3051 /* sp_adjust value may be out of range of the addi instruction,
3052 create alternative add behavior with TA_REGNUM if necessary,
3053 using POSITIVE value to tell that we are increasing address. */
3054 sp_adjust
= nds32_force_addi_stack_int (sp_adjust
);
3057 /* Generate sp adjustment instruction
3058 if and only if sp_adjust != 0. */
3059 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3061 GEN_INT (sp_adjust
));
3062 /* Emit rtx into instructions list and receive INSN rtx form. */
3063 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3065 /* The insn rtx 'sp_adjust_insn' will change frame layout. */
3066 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3070 /* Get callee_first_regno and callee_last_regno. */
3071 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_first_regno
);
3072 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_last_regno
);
3074 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
3075 the pattern 'stack_pop_multiple' is implementad in nds32.md.
3076 For En4 field, we have to calculate its constant value.
3077 Refer to Andes ISA for more information. */
3079 if (cfun
->machine
->fp_size
)
3081 if (cfun
->machine
->gp_size
)
3083 if (cfun
->machine
->lp_size
)
3086 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
3087 to be saved, we don't have to create multiple pop instruction.
3088 Otherwise, a multiple pop instruction is needed. */
3089 if (!(REGNO (Rb
) == SP_REGNUM
&& REGNO (Re
) == SP_REGNUM
&& en4_const
== 0))
3091 /* Create multiple pop instruction rtx. */
3092 nds32_emit_stack_pop_multiple (Rb
, Re
, GEN_INT (en4_const
));
3095 /* If this is a variadic function, we do not have to restore argument
3096 registers but need to adjust stack pointer back to previous stack
3097 frame location before return. */
3098 if (cfun
->machine
->va_args_size
!= 0)
3100 /* Generate sp adjustment instruction.
3101 We need to consider padding bytes here. */
3102 sp_adjust
= cfun
->machine
->va_args_size
3103 + cfun
->machine
->va_args_area_padding_bytes
;
3104 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3106 GEN_INT (sp_adjust
));
3107 /* Emit rtx into instructions list and receive INSN rtx form. */
3108 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3110 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3111 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3112 generate CFI (Call Frame Information) stuff. */
3113 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3116 /* Generate return instruction by using
3117 unspec_volatile_func_return pattern. */
3118 emit_insn (gen_unspec_volatile_func_return ());
3121 /* Function for v3push prologue. */
3123 nds32_expand_prologue_v3push (void)
3129 rtx fp_adjust_insn
, sp_adjust_insn
;
3131 /* Compute and setup stack frame size.
3132 The result will be in cfun->machine. */
3133 nds32_compute_stack_frame ();
3135 /* If the function is 'naked',
3136 we do not have to generate prologue code fragment. */
3137 if (cfun
->machine
->naked_p
)
3140 /* Get callee_first_regno and callee_last_regno. */
3141 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_first_regno
);
3142 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_last_regno
);
3144 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
3145 where imm8u has to be 8-byte alignment. */
3146 sp_adjust
= cfun
->machine
->local_size
3147 + cfun
->machine
->out_args_size
3148 + cfun
->machine
->callee_saved_area_padding_bytes
;
3150 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
3151 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
3153 /* We can use 'push25 Re,imm8u'. */
3155 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3156 the pattern 'stack_v3push' is implemented in nds32.md.
3157 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3158 nds32_emit_stack_v3push (Rb
, Re
,
3159 GEN_INT (14), GEN_INT (sp_adjust
));
3161 /* Check frame_pointer_needed to see
3162 if we shall emit fp adjustment instruction. */
3163 if (frame_pointer_needed
)
3165 /* adjust $fp = $sp + 4 ($fp size)
3168 + (4 * n) (callee-saved registers)
3169 + sp_adjust ('push25 Re,imm8u')
3170 Note: Since we use 'push25 Re,imm8u',
3171 the position of stack pointer is further
3172 changed after push instruction.
3173 Hence, we need to take sp_adjust value
3174 into consideration. */
3175 fp_adjust
= cfun
->machine
->fp_size
3176 + cfun
->machine
->gp_size
3177 + cfun
->machine
->lp_size
3178 + cfun
->machine
->callee_saved_regs_size
3180 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
3182 GEN_INT (fp_adjust
));
3183 /* Emit rtx into instructions list and receive INSN rtx form. */
3184 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
3189 /* We have to use 'push25 Re,0' and
3190 expand one more instruction to adjust $sp later. */
3192 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
3193 the pattern 'stack_v3push' is implemented in nds32.md.
3194 The (const_int 14) means v3push always push { $fp $gp $lp }. */
3195 nds32_emit_stack_v3push (Rb
, Re
,
3196 GEN_INT (14), GEN_INT (0));
3198 /* Check frame_pointer_needed to see
3199 if we shall emit fp adjustment instruction. */
3200 if (frame_pointer_needed
)
3202 /* adjust $fp = $sp + 4 ($fp size)
3205 + (4 * n) (callee-saved registers)
3206 Note: Since we use 'push25 Re,0',
3207 the stack pointer is just at the position
3208 after push instruction.
3209 No need to take sp_adjust into consideration. */
3210 fp_adjust
= cfun
->machine
->fp_size
3211 + cfun
->machine
->gp_size
3212 + cfun
->machine
->lp_size
3213 + cfun
->machine
->callee_saved_regs_size
;
3214 fp_adjust_insn
= gen_addsi3 (hard_frame_pointer_rtx
,
3216 GEN_INT (fp_adjust
));
3217 /* Emit rtx into instructions list and receive INSN rtx form. */
3218 fp_adjust_insn
= emit_insn (fp_adjust_insn
);
3221 /* Because we use 'push25 Re,0',
3222 we need to expand one more instruction to adjust $sp.
3223 However, sp_adjust value may be out of range of the addi instruction,
3224 create alternative add behavior with TA_REGNUM if necessary,
3225 using NEGATIVE value to tell that we are decreasing address. */
3226 sp_adjust
= nds32_force_addi_stack_int ( (-1) * sp_adjust
);
3229 /* Generate sp adjustment instruction
3230 if and only if sp_adjust != 0. */
3231 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3233 GEN_INT (-1 * sp_adjust
));
3234 /* Emit rtx into instructions list and receive INSN rtx form. */
3235 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3237 /* The insn rtx 'sp_adjust_insn' will change frame layout.
3238 We need to use RTX_FRAME_RELATED_P so that GCC is able to
3239 generate CFI (Call Frame Information) stuff. */
3240 RTX_FRAME_RELATED_P (sp_adjust_insn
) = 1;
3244 /* Prevent the instruction scheduler from
3245 moving instructions across the boundary. */
3246 emit_insn (gen_blockage ());
3249 /* Function for v3pop epilogue. */
3251 nds32_expand_epilogue_v3pop (void)
3258 /* Compute and setup stack frame size.
3259 The result will be in cfun->machine. */
3260 nds32_compute_stack_frame ();
3262 /* Prevent the instruction scheduler from
3263 moving instructions across the boundary. */
3264 emit_insn (gen_blockage ());
3266 /* If the function is 'naked', we do not have to generate
3267 epilogue code fragment BUT 'ret' instruction. */
3268 if (cfun
->machine
->naked_p
)
3270 /* Generate return instruction by using
3271 unspec_volatile_func_return pattern.
3272 Make sure this instruction is after gen_blockage().
3273 NOTE that $lp will become 'live'
3274 after this instruction has been emitted. */
3275 emit_insn (gen_unspec_volatile_func_return ());
3279 /* Get callee_first_regno and callee_last_regno. */
3280 Rb
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_first_regno
);
3281 Re
= gen_rtx_REG (SImode
, cfun
->machine
->callee_saved_regs_last_regno
);
3283 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3284 where imm8u has to be 8-byte alignment. */
3285 sp_adjust
= cfun
->machine
->local_size
3286 + cfun
->machine
->out_args_size
3287 + cfun
->machine
->callee_saved_area_padding_bytes
;
3289 /* We have to consider alloca issue as well.
3290 If the function does call alloca(), the stack pointer is not fixed.
3291 In that case, we cannot use 'pop25 Re,imm8u' directly.
3292 We have to caculate stack pointer from frame pointer
3293 and then use 'pop25 Re,0'.
3294 Of course, the frame_pointer_needed should be nonzero
3295 if the function calls alloca(). */
3296 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
3297 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
3298 && !cfun
->calls_alloca
)
3300 /* We can use 'pop25 Re,imm8u'. */
3302 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3303 the pattern 'stack_v3pop' is implementad in nds32.md.
3304 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3305 nds32_emit_stack_v3pop (Rb
, Re
,
3306 GEN_INT (14), GEN_INT (sp_adjust
));
3310 /* We have to use 'pop25 Re,0', and prior to it,
3311 we must expand one more instruction to adjust $sp. */
3313 if (frame_pointer_needed
)
3315 /* adjust $sp = $fp - 4 ($fp size)
3318 - (4 * n) (callee-saved registers)
3319 Note: No need to adjust
3320 cfun->machine->callee_saved_area_padding_bytes,
3321 because we want to adjust stack pointer
3322 to the position for pop instruction. */
3323 sp_adjust
= cfun
->machine
->fp_size
3324 + cfun
->machine
->gp_size
3325 + cfun
->machine
->lp_size
3326 + cfun
->machine
->callee_saved_regs_size
;
3327 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3328 hard_frame_pointer_rtx
,
3329 GEN_INT (-1 * sp_adjust
));
3330 /* Emit rtx into instructions list and receive INSN rtx form. */
3331 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3335 /* If frame pointer is NOT needed,
3336 we cannot calculate the sp adjustment from frame pointer.
3337 Instead, we calculate the adjustment by local_size,
3338 out_args_size, and callee_saved_area_padding_bytes.
3339 Notice that such sp adjustment value may be out of range,
3340 so we have to deal with it as well. */
3342 /* Adjust $sp = $sp + local_size + out_args_size
3343 + callee_saved_area_padding_bytes. */
3344 sp_adjust
= cfun
->machine
->local_size
3345 + cfun
->machine
->out_args_size
3346 + cfun
->machine
->callee_saved_area_padding_bytes
;
3347 /* sp_adjust value may be out of range of the addi instruction,
3348 create alternative add behavior with TA_REGNUM if necessary,
3349 using POSITIVE value to tell that we are increasing address. */
3350 sp_adjust
= nds32_force_addi_stack_int (sp_adjust
);
3353 /* Generate sp adjustment instruction
3354 if and only if sp_adjust != 0. */
3355 sp_adjust_insn
= gen_addsi3 (stack_pointer_rtx
,
3357 GEN_INT (sp_adjust
));
3358 /* Emit rtx into instructions list and receive INSN rtx form. */
3359 sp_adjust_insn
= emit_insn (sp_adjust_insn
);
3363 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3364 the pattern 'stack_v3pop' is implementad in nds32.md. */
3365 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3366 nds32_emit_stack_v3pop (Rb
, Re
,
3367 GEN_INT (14), GEN_INT (0));
3371 /* ------------------------------------------------------------------------ */
3373 /* Function to test 333-form for load/store instructions.
3374 This is auxiliary extern function for auxiliary macro in nds32.h.
3375 Because it is a little complicated, we use function instead of macro. */
3377 nds32_ls_333_p (rtx rt
, rtx ra
, rtx imm
, enum machine_mode mode
)
3379 if (REGNO_REG_CLASS (REGNO (rt
)) == LOW_REGS
3380 && REGNO_REG_CLASS (REGNO (ra
)) == LOW_REGS
)
3382 if (GET_MODE_SIZE (mode
) == 4)
3383 return satisfies_constraint_Iu05 (imm
);
3385 if (GET_MODE_SIZE (mode
) == 2)
3386 return satisfies_constraint_Iu04 (imm
);
3388 if (GET_MODE_SIZE (mode
) == 1)
3389 return satisfies_constraint_Iu03 (imm
);
3396 /* Computing the Length of an Insn.
3397 Modifies the length assigned to instruction INSN.
3398 LEN is the initially computed length of the insn. */
3400 nds32_adjust_insn_length (rtx_insn
*insn
, int length
)
3404 switch (recog_memoized (insn
))
3406 case CODE_FOR_move_df
:
3407 case CODE_FOR_move_di
:
3408 /* Adjust length of movd44 to 2. */
3409 src
= XEXP (PATTERN (insn
), 1);
3410 dst
= XEXP (PATTERN (insn
), 0);
3414 && (REGNO (src
) % 2) == 0
3415 && (REGNO (dst
) % 2) == 0)
3427 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3429 nds32_target_alignment (rtx label
)
3436 insn
= next_active_insn (label
);
3440 else if ((get_attr_length (insn
) % 4) == 0)
3446 /* ------------------------------------------------------------------------ */
3448 /* PART 5: Initialize target hook structure and definitions. */
3450 /* Controlling the Compilation Driver. */
3453 /* Run-time Target Specification. */
3456 /* Defining Data Structures for Per-function Information. */
3459 /* Storage Layout. */
3461 #undef TARGET_PROMOTE_FUNCTION_MODE
3462 #define TARGET_PROMOTE_FUNCTION_MODE \
3463 default_promote_function_mode_always_promote
3466 /* Layout of Source Language Data Types. */
3469 /* Register Usage. */
3471 /* -- Basic Characteristics of Registers. */
3473 /* -- Order of Allocation of Registers. */
3475 /* -- How Values Fit in Registers. */
3477 /* -- Handling Leaf Functions. */
3479 /* -- Registers That Form a Stack. */
3482 /* Register Classes. */
3484 #undef TARGET_CLASS_MAX_NREGS
3485 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3488 #define TARGET_LRA_P hook_bool_void_true
3490 #undef TARGET_REGISTER_PRIORITY
3491 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3494 /* Obsolete Macros for Defining Constraints. */
3497 /* Stack Layout and Calling Conventions. */
3499 /* -- Basic Stack Layout. */
3501 /* -- Exception Handling Support. */
3503 /* -- Specifying How Stack Checking is Done. */
3505 /* -- Registers That Address the Stack Frame. */
3507 /* -- Eliminating Frame Pointer and Arg Pointer. */
3509 #undef TARGET_CAN_ELIMINATE
3510 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3512 /* -- Passing Function Arguments on the Stack. */
3514 /* -- Passing Arguments in Registers. */
3516 #undef TARGET_FUNCTION_ARG
3517 #define TARGET_FUNCTION_ARG nds32_function_arg
3519 #undef TARGET_MUST_PASS_IN_STACK
3520 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
3522 #undef TARGET_ARG_PARTIAL_BYTES
3523 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
3525 #undef TARGET_FUNCTION_ARG_ADVANCE
3526 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3528 #undef TARGET_FUNCTION_ARG_BOUNDARY
3529 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3531 /* -- How Scalar Function Values Are Returned. */
3533 #undef TARGET_FUNCTION_VALUE
3534 #define TARGET_FUNCTION_VALUE nds32_function_value
3536 #undef TARGET_LIBCALL_VALUE
3537 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3539 #undef TARGET_FUNCTION_VALUE_REGNO_P
3540 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3542 /* -- How Large Values Are Returned. */
3544 /* -- Caller-Saves Register Allocation. */
3546 /* -- Function Entry and Exit. */
3548 #undef TARGET_ASM_FUNCTION_PROLOGUE
3549 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3551 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3552 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3554 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3555 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3557 #undef TARGET_ASM_FUNCTION_EPILOGUE
3558 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3560 #undef TARGET_ASM_OUTPUT_MI_THUNK
3561 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3563 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3564 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3566 /* -- Generating Code for Profiling. */
3568 /* -- Permitting tail calls. */
3570 #undef TARGET_WARN_FUNC_RETURN
3571 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3573 /* Stack smashing protection. */
3576 /* Implementing the Varargs Macros. */
3578 #undef TARGET_SETUP_INCOMING_VARARGS
3579 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
3581 #undef TARGET_STRICT_ARGUMENT_NAMING
3582 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3585 /* Trampolines for Nested Functions. */
3587 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3588 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3590 #undef TARGET_TRAMPOLINE_INIT
3591 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3594 /* Implicit Calls to Library Routines. */
3597 /* Addressing Modes. */
3599 #undef TARGET_LEGITIMATE_ADDRESS_P
3600 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3603 /* Anchored Addresses. */
3606 /* Condition Code Status. */
3608 /* -- Representation of condition codes using (cc0). */
3610 /* -- Representation of condition codes using registers. */
3612 /* -- Macros to control conditional execution. */
3615 /* Describing Relative Costs of Operations. */
3617 #undef TARGET_REGISTER_MOVE_COST
3618 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3620 #undef TARGET_MEMORY_MOVE_COST
3621 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3623 #undef TARGET_RTX_COSTS
3624 #define TARGET_RTX_COSTS nds32_rtx_costs
3626 #undef TARGET_ADDRESS_COST
3627 #define TARGET_ADDRESS_COST nds32_address_cost
3630 /* Adjusting the Instruction Scheduler. */
3633 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3636 /* Position Independent Code. */
3639 /* Defining the Output Assembler Language. */
3641 /* -- The Overall Framework of an Assembler File. */
3643 #undef TARGET_ASM_FILE_START
3644 #define TARGET_ASM_FILE_START nds32_asm_file_start
3645 #undef TARGET_ASM_FILE_END
3646 #define TARGET_ASM_FILE_END nds32_asm_file_end
3648 /* -- Output of Data. */
3650 #undef TARGET_ASM_ALIGNED_HI_OP
3651 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3653 #undef TARGET_ASM_ALIGNED_SI_OP
3654 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3656 /* -- Output of Uninitialized Variables. */
3658 /* -- Output and Generation of Labels. */
3660 #undef TARGET_ASM_GLOBALIZE_LABEL
3661 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3663 /* -- How Initialization Functions Are Handled. */
3665 /* -- Macros Controlling Initialization Routines. */
3667 /* -- Output of Assembler Instructions. */
3669 #undef TARGET_PRINT_OPERAND
3670 #define TARGET_PRINT_OPERAND nds32_print_operand
3671 #undef TARGET_PRINT_OPERAND_ADDRESS
3672 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3674 /* -- Output of Dispatch Tables. */
3676 /* -- Assembler Commands for Exception Regions. */
3678 /* -- Assembler Commands for Alignment. */
3681 /* Controlling Debugging Information Format. */
3683 /* -- Macros Affecting All Debugging Formats. */
3685 /* -- Specific Options for DBX Output. */
3687 /* -- Open-Ended Hooks for DBX Format. */
3689 /* -- File Names in DBX Format. */
3691 /* -- Macros for SDB and DWARF Output. */
3693 /* -- Macros for VMS Debug Format. */
3696 /* Cross Compilation and Floating Point. */
3699 /* Mode Switching Instructions. */
3702 /* Defining target-specific uses of __attribute__. */
3704 #undef TARGET_ATTRIBUTE_TABLE
3705 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3707 #undef TARGET_MERGE_DECL_ATTRIBUTES
3708 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3710 #undef TARGET_INSERT_ATTRIBUTES
3711 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3713 #undef TARGET_OPTION_PRAGMA_PARSE
3714 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3716 #undef TARGET_OPTION_OVERRIDE
3717 #define TARGET_OPTION_OVERRIDE nds32_option_override
3720 /* Emulating TLS. */
3723 /* Defining coprocessor specifics for MIPS targets. */
3726 /* Parameters for Precompiled Header Validity Checking. */
3729 /* C++ ABI parameters. */
3732 /* Adding support for named address spaces. */
3735 /* Miscellaneous Parameters. */
3737 #undef TARGET_INIT_BUILTINS
3738 #define TARGET_INIT_BUILTINS nds32_init_builtins
3740 #undef TARGET_EXPAND_BUILTIN
3741 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3744 /* ------------------------------------------------------------------------ */
3746 /* Initialize the GCC target structure. */
3748 struct gcc_target targetm
= TARGET_INITIALIZER
;
3750 /* ------------------------------------------------------------------------ */