libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / config / nds32 / nds32.cc
blobf5ea1daad4048a20051afde39f2f2b4d4842dc54
1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2024 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #define IN_TARGET_CODE 1
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "backend.h"
29 #include "target.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "tree-pass.h"
33 #include "stringpool.h"
34 #include "attribs.h"
35 #include "df.h"
36 #include "memmodel.h"
37 #include "tm_p.h"
38 #include "optabs.h" /* For GEN_FCN. */
39 #include "regs.h"
40 #include "emit-rtl.h"
41 #include "recog.h"
42 #include "diagnostic-core.h"
43 #include "stor-layout.h"
44 #include "varasm.h"
45 #include "calls.h"
46 #include "output.h"
47 #include "explow.h"
48 #include "expr.h"
49 #include "tm-constrs.h"
50 #include "builtins.h"
51 #include "cpplib.h"
52 #include "context.h"
54 /* This file should be included last. */
55 #include "target-def.h"
57 /* ------------------------------------------------------------------------ */
59 /* This file is divided into five parts:
61 PART 1: Auxiliary static variable definitions and
62 target hook static variable definitions.
64 PART 2: Auxiliary static function definitions.
66 PART 3: Implement target hook stuff definitions.
68 PART 4: Implemet extern function definitions,
69 the prototype is in nds32-protos.h.
71 PART 5: Initialize target hook structure and definitions. */
73 /* ------------------------------------------------------------------------ */
75 /* PART 1: Auxiliary static variable definitions and
76 target hook static variable definitions. */
78 /* Define intrinsic register names.
79 Please refer to nds32_intrinsic.h file, the index is corresponding to
80 'enum nds32_intrinsic_registers' data type values.
81 NOTE that the base value starting from 1024. */
82 static const char * const nds32_intrinsic_register_names[] =
84 "$CPU_VER",
85 "$ICM_CFG",
86 "$DCM_CFG",
87 "$MMU_CFG",
88 "$MSC_CFG",
89 "$MSC_CFG2",
90 "$CORE_ID",
91 "$FUCOP_EXIST",
93 "$PSW",
94 "$IPSW",
95 "$P_IPSW",
96 "$IVB",
97 "$EVA",
98 "$P_EVA",
99 "$ITYPE",
100 "$P_ITYPE",
102 "$MERR",
103 "$IPC",
104 "$P_IPC",
105 "$OIPC",
106 "$P_P0",
107 "$P_P1",
109 "$INT_MASK",
110 "$INT_MASK2",
111 "$INT_MASK3",
112 "$INT_PEND",
113 "$INT_PEND2",
114 "$INT_PEND3",
115 "$SP_USR",
116 "$SP_PRIV",
117 "$INT_PRI",
118 "$INT_PRI2",
119 "$INT_PRI3",
120 "$INT_PRI4",
121 "$INT_CTRL",
122 "$INT_TRIGGER",
123 "$INT_TRIGGER2",
124 "$INT_GPR_PUSH_DIS",
126 "$MMU_CTL",
127 "$L1_PPTB",
128 "$TLB_VPN",
129 "$TLB_DATA",
130 "$TLB_MISC",
131 "$VLPT_IDX",
132 "$ILMB",
133 "$DLMB",
135 "$CACHE_CTL",
136 "$HSMP_SADDR",
137 "$HSMP_EADDR",
138 "$SDZ_CTL",
139 "$N12MISC_CTL",
140 "$MISC_CTL",
141 "$ECC_MISC",
143 "$BPC0",
144 "$BPC1",
145 "$BPC2",
146 "$BPC3",
147 "$BPC4",
148 "$BPC5",
149 "$BPC6",
150 "$BPC7",
152 "$BPA0",
153 "$BPA1",
154 "$BPA2",
155 "$BPA3",
156 "$BPA4",
157 "$BPA5",
158 "$BPA6",
159 "$BPA7",
161 "$BPAM0",
162 "$BPAM1",
163 "$BPAM2",
164 "$BPAM3",
165 "$BPAM4",
166 "$BPAM5",
167 "$BPAM6",
168 "$BPAM7",
170 "$BPV0",
171 "$BPV1",
172 "$BPV2",
173 "$BPV3",
174 "$BPV4",
175 "$BPV5",
176 "$BPV6",
177 "$BPV7",
179 "$BPCID0",
180 "$BPCID1",
181 "$BPCID2",
182 "$BPCID3",
183 "$BPCID4",
184 "$BPCID5",
185 "$BPCID6",
186 "$BPCID7",
188 "$EDM_CFG",
189 "$EDMSW",
190 "$EDM_CTL",
191 "$EDM_DTR",
192 "$BPMTC",
193 "$DIMBR",
195 "$TECR0",
196 "$TECR1",
197 "$PFMC0",
198 "$PFMC1",
199 "$PFMC2",
200 "$PFM_CTL",
201 "$PFT_CTL",
202 "$HSP_CTL",
203 "$SP_BOUND",
204 "$SP_BOUND_PRIV",
205 "$SP_BASE",
206 "$SP_BASE_PRIV",
207 "$FUCOP_CTL",
208 "$PRUSR_ACC_CTL",
210 "$DMA_CFG",
211 "$DMA_GCSW",
212 "$DMA_CHNSEL",
213 "$DMA_ACT",
214 "$DMA_SETUP",
215 "$DMA_ISADDR",
216 "$DMA_ESADDR",
217 "$DMA_TCNT",
218 "$DMA_STATUS",
219 "$DMA_2DSET",
220 "$DMA_2DSCTL",
221 "$DMA_RCNT",
222 "$DMA_HSTATUS",
224 "$PC",
225 "$SP_USR1",
226 "$SP_USR2",
227 "$SP_USR3",
228 "$SP_PRIV1",
229 "$SP_PRIV2",
230 "$SP_PRIV3",
231 "$BG_REGION",
232 "$SFCR",
233 "$SIGN",
234 "$ISIGN",
235 "$P_ISIGN",
236 "$IFC_LP",
237 "$ITB"
240 /* Define instrinsic cctl names. */
241 static const char * const nds32_cctl_names[] =
243 "L1D_VA_FILLCK",
244 "L1D_VA_ULCK",
245 "L1I_VA_FILLCK",
246 "L1I_VA_ULCK",
248 "L1D_IX_WBINVAL",
249 "L1D_IX_INVAL",
250 "L1D_IX_WB",
251 "L1I_IX_INVAL",
253 "L1D_VA_INVAL",
254 "L1D_VA_WB",
255 "L1D_VA_WBINVAL",
256 "L1I_VA_INVAL",
258 "L1D_IX_RTAG",
259 "L1D_IX_RWD",
260 "L1I_IX_RTAG",
261 "L1I_IX_RWD",
263 "L1D_IX_WTAG",
264 "L1D_IX_WWD",
265 "L1I_IX_WTAG",
266 "L1I_IX_WWD"
269 static const char * const nds32_dpref_names[] =
271 "SRD",
272 "MRD",
273 "SWR",
274 "MWR",
275 "PTE",
276 "CLWR"
279 /* Defining register allocation order for performance.
280 We want to allocate callee-saved registers after others.
281 It may be used by nds32_adjust_reg_alloc_order(). */
282 static const int nds32_reg_alloc_order_for_speed[] =
284 0, 1, 2, 3, 4, 5, 16, 17,
285 18, 19, 20, 21, 22, 23, 24, 25,
286 26, 27, 6, 7, 8, 9, 10, 11,
287 12, 13, 14, 15
290 /* Defining target-specific uses of __attribute__. */
291 TARGET_GNU_ATTRIBUTES (nds32_attribute_table,
293 /* Syntax: { name, min_len, max_len, decl_required, type_required,
294 function_type_required, affects_type_identity, handler,
295 exclude } */
297 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
298 { "interrupt", 1, 64, false, false, false, false, NULL, NULL },
299 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
300 { "exception", 1, 8, false, false, false, false, NULL, NULL },
301 /* Argument is user's interrupt numbers. The vector number is always 0. */
302 { "reset", 1, 1, false, false, false, false, NULL, NULL },
304 /* The attributes describing isr nested type. */
305 { "nested", 0, 0, false, false, false, false, NULL, NULL },
306 { "not_nested", 0, 0, false, false, false, false, NULL, NULL },
307 { "nested_ready", 0, 0, false, false, false, false, NULL, NULL },
308 { "critical", 0, 0, false, false, false, false, NULL, NULL },
310 /* The attributes describing isr register save scheme. */
311 { "save_all", 0, 0, false, false, false, false, NULL, NULL },
312 { "partial_save", 0, 0, false, false, false, false, NULL, NULL },
314 /* The attributes used by reset attribute. */
315 { "nmi", 1, 1, false, false, false, false, NULL, NULL },
316 { "warm", 1, 1, false, false, false, false, NULL, NULL },
318 /* The attributes describing isr security level. */
319 { "secure", 1, 1, false, false, false, false, NULL, NULL },
321 /* The attribute telling no prologue/epilogue. */
322 { "naked", 0, 0, false, false, false, false, NULL, NULL },
324 /* The attribute is used to tell this function to be ROM patch. */
325 { "indirect_call",0, 0, false, false, false, false, NULL, NULL },
327 /* FOR BACKWARD COMPATIBILITY,
328 this attribute also tells no prologue/epilogue. */
329 { "no_prologue", 0, 0, false, false, false, false, NULL, NULL }
333 /* ------------------------------------------------------------------------ */
335 /* PART 2: Auxiliary static function definitions. */
337 /* Function to save and restore machine-specific function data. */
338 static struct machine_function *
339 nds32_init_machine_status (void)
341 struct machine_function *machine;
342 machine = ggc_cleared_alloc<machine_function> ();
344 /* Initially assume this function does not use __builtin_eh_return. */
345 machine->use_eh_return_p = 0;
347 /* Initially assume this function needs prologue/epilogue. */
348 machine->naked_p = 0;
350 /* Initially assume this function does NOT use fp_as_gp optimization. */
351 machine->fp_as_gp_p = 0;
353 /* Initially this function is not under strictly aligned situation. */
354 machine->strict_aligned_p = 0;
356 /* Initially this function has no naked and no_prologue attributes. */
357 machine->attr_naked_p = 0;
358 machine->attr_no_prologue_p = 0;
360 return machine;
363 /* Function to compute stack frame size and
364 store into cfun->machine structure. */
365 static void
366 nds32_compute_stack_frame (void)
368 int r;
369 int block_size;
370 bool v3pushpop_p;
372 /* Because nds32_compute_stack_frame() will be called from different place,
373 everytime we enter this function, we have to assume this function
374 needs prologue/epilogue. */
375 cfun->machine->naked_p = 0;
377 /* We need to mark whether this function has naked and no_prologue
378 attribute so that we can distinguish the difference if users applies
379 -mret-in-naked-func option. */
380 cfun->machine->attr_naked_p
381 = lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
382 ? 1 : 0;
383 cfun->machine->attr_no_prologue_p
384 = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl))
385 ? 1 : 0;
387 /* If __builtin_eh_return is used, we better have frame pointer needed
388 so that we can easily locate the stack slot of return address. */
389 if (crtl->calls_eh_return)
391 frame_pointer_needed = 1;
393 /* We need to mark eh data registers that need to be saved
394 in the stack. */
395 cfun->machine->eh_return_data_first_regno = EH_RETURN_DATA_REGNO (0);
396 for (r = 0; EH_RETURN_DATA_REGNO (r) != INVALID_REGNUM; r++)
397 cfun->machine->eh_return_data_last_regno = r;
399 cfun->machine->eh_return_data_regs_size
400 = 4 * (cfun->machine->eh_return_data_last_regno
401 - cfun->machine->eh_return_data_first_regno
402 + 1);
403 cfun->machine->use_eh_return_p = 1;
405 else
407 /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we
408 do not need to handle __builtin_eh_return case in this function. */
409 cfun->machine->eh_return_data_first_regno = SP_REGNUM;
410 cfun->machine->eh_return_data_last_regno = SP_REGNUM;
412 cfun->machine->eh_return_data_regs_size = 0;
413 cfun->machine->use_eh_return_p = 0;
416 /* Get variadic arguments size to prepare pretend arguments and
417 we will push them into stack at prologue by ourself. */
418 cfun->machine->va_args_size = crtl->args.pretend_args_size;
419 if (cfun->machine->va_args_size != 0)
421 cfun->machine->va_args_first_regno
422 = NDS32_GPR_ARG_FIRST_REGNUM
423 + NDS32_MAX_GPR_REGS_FOR_ARGS
424 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
425 cfun->machine->va_args_last_regno
426 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
428 else
430 cfun->machine->va_args_first_regno = SP_REGNUM;
431 cfun->machine->va_args_last_regno = SP_REGNUM;
434 /* Important: We need to make sure that varargs area is 8-byte alignment. */
435 block_size = cfun->machine->va_args_size;
436 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
438 cfun->machine->va_args_area_padding_bytes
439 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
442 /* Get local variables, incoming variables, and temporary variables size.
443 Note that we need to make sure it is 8-byte alignment because
444 there may be no padding bytes if we are using LRA. */
445 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
447 /* Get outgoing arguments size. */
448 cfun->machine->out_args_size = crtl->outgoing_args_size;
450 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
451 Check whether $fp is ever live. */
452 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
454 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
455 Check whether we are using PIC code genration. */
456 cfun->machine->gp_size =
457 (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) ? 4 : 0;
459 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
460 Check whether $lp is ever live. */
461 cfun->machine->lp_size
462 = (flag_always_save_lp || df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
464 /* Initially there is no padding bytes. */
465 cfun->machine->callee_saved_area_gpr_padding_bytes = 0;
467 /* Calculate the bytes of saving callee-saved registers on stack. */
468 cfun->machine->callee_saved_gpr_regs_size = 0;
469 cfun->machine->callee_saved_first_gpr_regno = SP_REGNUM;
470 cfun->machine->callee_saved_last_gpr_regno = SP_REGNUM;
471 cfun->machine->callee_saved_fpr_regs_size = 0;
472 cfun->machine->callee_saved_first_fpr_regno = SP_REGNUM;
473 cfun->machine->callee_saved_last_fpr_regno = SP_REGNUM;
475 /* Currently, there is no need to check $r28~$r31
476 because we will save them in another way. */
477 for (r = 0; r < 28; r++)
479 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
481 /* Mark the first required callee-saved register
482 (only need to set it once).
483 If first regno == SP_REGNUM, we can tell that
484 it is the first time to be here. */
485 if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM)
486 cfun->machine->callee_saved_first_gpr_regno = r;
487 /* Mark the last required callee-saved register. */
488 cfun->machine->callee_saved_last_gpr_regno = r;
492 /* Recording fpu callee-saved register. */
493 if (TARGET_HARD_FLOAT)
495 for (r = NDS32_FIRST_FPR_REGNUM; r < NDS32_LAST_FPR_REGNUM; r++)
497 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
499 /* Mark the first required callee-saved register. */
500 if (cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM)
502 /* Make first callee-saved number is even,
503 bacause we use doubleword access, and this way
504 promise 8-byte alignemt. */
505 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r))
506 cfun->machine->callee_saved_first_fpr_regno = r - 1;
507 else
508 cfun->machine->callee_saved_first_fpr_regno = r;
510 cfun->machine->callee_saved_last_fpr_regno = r;
514 /* Make last callee-saved register number is odd,
515 we hope callee-saved register is even. */
516 int last_fpr = cfun->machine->callee_saved_last_fpr_regno;
517 if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr))
518 cfun->machine->callee_saved_last_fpr_regno++;
521 /* Check if this function can omit prologue/epilogue code fragment.
522 If there is 'no_prologue'/'naked'/'secure' attribute in this function,
523 we can set 'naked_p' flag to indicate that
524 we do not have to generate prologue/epilogue.
525 Or, if all the following conditions succeed,
526 we can set this function 'naked_p' as well:
527 condition 1: first_regno == last_regno == SP_REGNUM,
528 which means we do not have to save
529 any callee-saved registers.
530 condition 2: Both $lp and $fp are NOT live in this function,
531 which means we do not need to save them and there
532 is no outgoing size.
533 condition 3: There is no local_size, which means
534 we do not need to adjust $sp. */
535 if (lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl))
536 || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
537 || lookup_attribute ("secure", DECL_ATTRIBUTES (current_function_decl))
538 || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM
539 && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM
540 && cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM
541 && cfun->machine->callee_saved_last_fpr_regno == SP_REGNUM
542 && !df_regs_ever_live_p (FP_REGNUM)
543 && !df_regs_ever_live_p (LP_REGNUM)
544 && cfun->machine->local_size == 0
545 && !flag_pic))
547 /* Set this function 'naked_p' and other functions can check this flag.
548 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
549 callee-saved, local size, and outgoing size.
550 The varargs space and ret instruction may still present in
551 the prologue/epilogue expanding. */
552 cfun->machine->naked_p = 1;
554 /* No need to save $fp, $gp, and $lp.
555 We should set these value to be zero
556 so that nds32_initial_elimination_offset() can work properly. */
557 cfun->machine->fp_size = 0;
558 cfun->machine->gp_size = 0;
559 cfun->machine->lp_size = 0;
561 /* If stack usage computation is required,
562 we need to provide the static stack size. */
563 if (flag_stack_usage_info)
564 current_function_static_stack_size = 0;
566 /* No need to do following adjustment, return immediately. */
567 return;
570 v3pushpop_p = NDS32_V3PUSH_AVAILABLE_P;
572 /* Adjustment for v3push instructions:
573 If we are using v3push (push25/pop25) instructions,
574 we need to make sure Rb is $r6 and Re is
575 located on $r6, $r8, $r10, or $r14.
576 Some results above will be discarded and recomputed.
577 Note that it is only available under V3/V3M ISA and we
578 DO NOT setup following stuff for isr or variadic function. */
579 if (v3pushpop_p)
581 /* Recompute:
582 cfun->machine->fp_size
583 cfun->machine->gp_size
584 cfun->machine->lp_size
585 cfun->machine->callee_saved_first_gpr_regno
586 cfun->machine->callee_saved_last_gpr_regno */
588 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
589 cfun->machine->fp_size = 4;
590 cfun->machine->gp_size = 4;
591 cfun->machine->lp_size = 4;
593 /* Remember to set Rb = $r6. */
594 cfun->machine->callee_saved_first_gpr_regno = 6;
596 if (cfun->machine->callee_saved_last_gpr_regno <= 6)
598 /* Re = $r6 */
599 cfun->machine->callee_saved_last_gpr_regno = 6;
601 else if (cfun->machine->callee_saved_last_gpr_regno <= 8)
603 /* Re = $r8 */
604 cfun->machine->callee_saved_last_gpr_regno = 8;
606 else if (cfun->machine->callee_saved_last_gpr_regno <= 10)
608 /* Re = $r10 */
609 cfun->machine->callee_saved_last_gpr_regno = 10;
611 else if (cfun->machine->callee_saved_last_gpr_regno <= 14)
613 /* Re = $r14 */
614 cfun->machine->callee_saved_last_gpr_regno = 14;
616 else if (cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM)
618 /* If last_regno is SP_REGNUM, which means
619 it is never changed, so set it to Re = $r6. */
620 cfun->machine->callee_saved_last_gpr_regno = 6;
622 else
624 /* The program flow should not go here. */
625 gcc_unreachable ();
629 int sp_adjust = cfun->machine->local_size
630 + cfun->machine->out_args_size
631 + cfun->machine->callee_saved_area_gpr_padding_bytes
632 + cfun->machine->callee_saved_fpr_regs_size;
634 if (!v3pushpop_p
635 && sp_adjust == 0
636 && !frame_pointer_needed)
638 block_size = cfun->machine->fp_size
639 + cfun->machine->gp_size
640 + cfun->machine->lp_size;
642 if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM)
643 block_size += (4 * (cfun->machine->callee_saved_last_gpr_regno
644 - cfun->machine->callee_saved_first_gpr_regno
645 + 1));
647 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
649 /* $r14 is last callee save register. */
650 if (cfun->machine->callee_saved_last_gpr_regno
651 < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM)
653 cfun->machine->callee_saved_last_gpr_regno++;
655 else if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM)
657 cfun->machine->callee_saved_first_gpr_regno
658 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM;
659 cfun->machine->callee_saved_last_gpr_regno
660 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM;
665 /* We have correctly set callee_saved_first_gpr_regno
666 and callee_saved_last_gpr_regno.
667 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
668 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
669 we can update callee_saved_gpr_regs_size with new size. */
670 if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM)
672 /* Compute pushed size of callee-saved registers. */
673 cfun->machine->callee_saved_gpr_regs_size
674 = 4 * (cfun->machine->callee_saved_last_gpr_regno
675 - cfun->machine->callee_saved_first_gpr_regno
676 + 1);
679 if (TARGET_HARD_FLOAT)
681 /* Compute size of callee svaed floating-point registers. */
682 if (cfun->machine->callee_saved_last_fpr_regno != SP_REGNUM)
684 cfun->machine->callee_saved_fpr_regs_size
685 = 4 * (cfun->machine->callee_saved_last_fpr_regno
686 - cfun->machine->callee_saved_first_fpr_regno
687 + 1);
691 /* Important: We need to make sure that
692 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
693 is 8-byte alignment.
694 If it is not, calculate the padding bytes. */
695 block_size = cfun->machine->fp_size
696 + cfun->machine->gp_size
697 + cfun->machine->lp_size
698 + cfun->machine->callee_saved_gpr_regs_size;
699 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
701 cfun->machine->callee_saved_area_gpr_padding_bytes
702 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
705 /* If stack usage computation is required,
706 we need to provide the static stack size. */
707 if (flag_stack_usage_info)
709 current_function_static_stack_size
710 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
711 + cfun->machine->local_size
712 + cfun->machine->out_args_size;
716 /* Function to create a parallel rtx pattern
717 which presents stack push multiple behavior.
718 The overall concept are:
719 "push registers to memory",
720 "adjust stack pointer". */
721 static void
722 nds32_emit_stack_push_multiple (unsigned Rb, unsigned Re,
723 bool save_fp_p, bool save_gp_p, bool save_lp_p,
724 bool vaarg_p)
726 unsigned regno;
727 int extra_count;
728 int num_use_regs;
729 int par_index;
730 int offset;
732 rtx reg;
733 rtx mem;
734 rtx push_rtx;
735 rtx adjust_sp_rtx;
736 rtx parallel_insn;
737 rtx dwarf;
739 /* We need to provide a customized rtx which contains
740 necessary information for data analysis,
741 so we create a parallel rtx like this:
742 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
743 (reg:SI Rb))
744 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
745 (reg:SI Rb+1))
747 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
748 (reg:SI Re))
749 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
750 (reg:SI FP_REGNUM))
751 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
752 (reg:SI GP_REGNUM))
753 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
754 (reg:SI LP_REGNUM))
755 (set (reg:SI SP_REGNUM)
756 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
758 /* Calculate the number of registers that will be pushed. */
759 extra_count = 0;
760 if (save_fp_p)
761 extra_count++;
762 if (save_gp_p)
763 extra_count++;
764 if (save_lp_p)
765 extra_count++;
766 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
767 if (Rb == SP_REGNUM && Re == SP_REGNUM)
768 num_use_regs = extra_count;
769 else
770 num_use_regs = Re - Rb + 1 + extra_count;
772 /* In addition to used registers,
773 we need one more space for (set sp sp-x) rtx. */
774 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
775 rtvec_alloc (num_use_regs + 1));
776 par_index = 0;
778 /* Initialize offset and start to create push behavior. */
779 offset = -(num_use_regs * 4);
781 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
782 for (regno = Rb; regno <= Re; regno++)
784 /* Rb and Re may be SP_REGNUM.
785 We need to break this loop immediately. */
786 if (regno == SP_REGNUM)
787 break;
789 reg = gen_rtx_REG (SImode, regno);
790 mem = gen_frame_mem (SImode, plus_constant (Pmode,
791 stack_pointer_rtx,
792 offset));
793 push_rtx = gen_rtx_SET (mem, reg);
794 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
795 RTX_FRAME_RELATED_P (push_rtx) = 1;
796 offset = offset + 4;
797 par_index++;
800 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
801 if (save_fp_p)
803 reg = gen_rtx_REG (SImode, FP_REGNUM);
804 mem = gen_frame_mem (SImode, plus_constant (Pmode,
805 stack_pointer_rtx,
806 offset));
807 push_rtx = gen_rtx_SET (mem, reg);
808 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
809 RTX_FRAME_RELATED_P (push_rtx) = 1;
810 offset = offset + 4;
811 par_index++;
813 if (save_gp_p)
815 reg = gen_rtx_REG (SImode, GP_REGNUM);
816 mem = gen_frame_mem (SImode, plus_constant (Pmode,
817 stack_pointer_rtx,
818 offset));
819 push_rtx = gen_rtx_SET (mem, reg);
820 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
821 RTX_FRAME_RELATED_P (push_rtx) = 1;
822 offset = offset + 4;
823 par_index++;
825 if (save_lp_p)
827 reg = gen_rtx_REG (SImode, LP_REGNUM);
828 mem = gen_frame_mem (SImode, plus_constant (Pmode,
829 stack_pointer_rtx,
830 offset));
831 push_rtx = gen_rtx_SET (mem, reg);
832 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
833 RTX_FRAME_RELATED_P (push_rtx) = 1;
834 offset = offset + 4;
835 par_index++;
838 /* Create (set sp sp-x). */
840 /* We need to re-calculate the offset value again for adjustment. */
841 offset = -(num_use_regs * 4);
842 adjust_sp_rtx
843 = gen_rtx_SET (stack_pointer_rtx,
844 plus_constant (Pmode, stack_pointer_rtx, offset));
845 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
846 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
848 parallel_insn = emit_insn (parallel_insn);
850 /* The insn rtx 'parallel_insn' will change frame layout.
851 We need to use RTX_FRAME_RELATED_P so that GCC is able to
852 generate CFI (Call Frame Information) stuff. */
853 RTX_FRAME_RELATED_P (parallel_insn) = 1;
855 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
856 since we will not restore those register at epilogue. */
857 if (vaarg_p)
859 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
860 copy_rtx (adjust_sp_rtx), NULL_RTX);
861 REG_NOTES (parallel_insn) = dwarf;
865 /* Function to create a parallel rtx pattern
866 which presents stack pop multiple behavior.
867 The overall concept are:
868 "pop registers from memory",
869 "adjust stack pointer". */
870 static void
871 nds32_emit_stack_pop_multiple (unsigned Rb, unsigned Re,
872 bool save_fp_p, bool save_gp_p, bool save_lp_p)
874 unsigned regno;
875 int extra_count;
876 int num_use_regs;
877 int par_index;
878 int offset;
880 rtx reg;
881 rtx mem;
882 rtx pop_rtx;
883 rtx adjust_sp_rtx;
884 rtx parallel_insn;
885 rtx dwarf = NULL_RTX;
887 /* We need to provide a customized rtx which contains
888 necessary information for data analysis,
889 so we create a parallel rtx like this:
890 (parallel [(set (reg:SI Rb)
891 (mem (reg:SI SP_REGNUM)))
892 (set (reg:SI Rb+1)
893 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
895 (set (reg:SI Re)
896 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
897 (set (reg:SI FP_REGNUM)
898 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
899 (set (reg:SI GP_REGNUM)
900 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
901 (set (reg:SI LP_REGNUM)
902 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
903 (set (reg:SI SP_REGNUM)
904 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
906 /* Calculate the number of registers that will be poped. */
907 extra_count = 0;
908 if (save_fp_p)
909 extra_count++;
910 if (save_gp_p)
911 extra_count++;
912 if (save_lp_p)
913 extra_count++;
914 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
915 if (Rb == SP_REGNUM && Re == SP_REGNUM)
916 num_use_regs = extra_count;
917 else
918 num_use_regs = Re - Rb + 1 + extra_count;
920 /* In addition to used registers,
921 we need one more space for (set sp sp+x) rtx. */
922 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
923 rtvec_alloc (num_use_regs + 1));
924 par_index = 0;
926 /* Initialize offset and start to create pop behavior. */
927 offset = 0;
929 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
930 for (regno = Rb; regno <= Re; regno++)
932 /* Rb and Re may be SP_REGNUM.
933 We need to break this loop immediately. */
934 if (regno == SP_REGNUM)
935 break;
937 reg = gen_rtx_REG (SImode, regno);
938 mem = gen_frame_mem (SImode, plus_constant (Pmode,
939 stack_pointer_rtx,
940 offset));
941 pop_rtx = gen_rtx_SET (reg, mem);
942 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
943 RTX_FRAME_RELATED_P (pop_rtx) = 1;
944 offset = offset + 4;
945 par_index++;
947 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
950 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
951 if (save_fp_p)
953 reg = gen_rtx_REG (SImode, FP_REGNUM);
954 mem = gen_frame_mem (SImode, plus_constant (Pmode,
955 stack_pointer_rtx,
956 offset));
957 pop_rtx = gen_rtx_SET (reg, mem);
958 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
959 RTX_FRAME_RELATED_P (pop_rtx) = 1;
960 offset = offset + 4;
961 par_index++;
963 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
965 if (save_gp_p)
967 reg = gen_rtx_REG (SImode, GP_REGNUM);
968 mem = gen_frame_mem (SImode, plus_constant (Pmode,
969 stack_pointer_rtx,
970 offset));
971 pop_rtx = gen_rtx_SET (reg, mem);
972 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
973 RTX_FRAME_RELATED_P (pop_rtx) = 1;
974 offset = offset + 4;
975 par_index++;
977 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
979 if (save_lp_p)
981 reg = gen_rtx_REG (SImode, LP_REGNUM);
982 mem = gen_frame_mem (SImode, plus_constant (Pmode,
983 stack_pointer_rtx,
984 offset));
985 pop_rtx = gen_rtx_SET (reg, mem);
986 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
987 RTX_FRAME_RELATED_P (pop_rtx) = 1;
988 offset = offset + 4;
989 par_index++;
991 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
994 /* Create (set sp sp+x). */
996 /* The offset value is already in place. No need to re-calculate it. */
997 adjust_sp_rtx
998 = gen_rtx_SET (stack_pointer_rtx,
999 plus_constant (Pmode, stack_pointer_rtx, offset));
1000 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
1002 /* Tell gcc we adjust SP in this insn. */
1003 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
1005 parallel_insn = emit_insn (parallel_insn);
1007 /* The insn rtx 'parallel_insn' will change frame layout.
1008 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1009 generate CFI (Call Frame Information) stuff. */
1010 RTX_FRAME_RELATED_P (parallel_insn) = 1;
1012 /* Add CFI info by manual. */
1013 REG_NOTES (parallel_insn) = dwarf;
1016 /* Function to create a parallel rtx pattern
1017 which presents stack v3push behavior.
1018 The overall concept are:
1019 "push registers to memory",
1020 "adjust stack pointer". */
1021 static void
1022 nds32_emit_stack_v3push (unsigned Rb,
1023 unsigned Re,
1024 unsigned imm8u)
1026 unsigned regno;
1027 int num_use_regs;
1028 int par_index;
1029 int offset;
1031 rtx reg;
1032 rtx mem;
1033 rtx push_rtx;
1034 rtx adjust_sp_rtx;
1035 rtx parallel_insn;
1037 /* We need to provide a customized rtx which contains
1038 necessary information for data analysis,
1039 so we create a parallel rtx like this:
1040 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
1041 (reg:SI Rb))
1042 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
1043 (reg:SI Rb+1))
1045 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
1046 (reg:SI Re))
1047 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
1048 (reg:SI FP_REGNUM))
1049 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
1050 (reg:SI GP_REGNUM))
1051 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
1052 (reg:SI LP_REGNUM))
1053 (set (reg:SI SP_REGNUM)
1054 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
1056 /* Calculate the number of registers that will be pushed.
1057 Since $fp, $gp, and $lp is always pushed with v3push instruction,
1058 we need to count these three registers.
1059 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1060 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1061 num_use_regs = Re - Rb + 1 + 3;
1063 /* In addition to used registers,
1064 we need one more space for (set sp sp-x-imm8u) rtx. */
1065 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
1066 rtvec_alloc (num_use_regs + 1));
1067 par_index = 0;
1069 /* Initialize offset and start to create push behavior. */
1070 offset = -(num_use_regs * 4);
1072 /* Create (set mem regX) from Rb, Rb+1 up to Re.
1073 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1074 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1075 for (regno = Rb; regno <= Re; regno++)
1077 reg = gen_rtx_REG (SImode, regno);
1078 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1079 stack_pointer_rtx,
1080 offset));
1081 push_rtx = gen_rtx_SET (mem, reg);
1082 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1083 RTX_FRAME_RELATED_P (push_rtx) = 1;
1084 offset = offset + 4;
1085 par_index++;
1088 /* Create (set mem fp). */
1089 reg = gen_rtx_REG (SImode, FP_REGNUM);
1090 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1091 stack_pointer_rtx,
1092 offset));
1093 push_rtx = gen_rtx_SET (mem, reg);
1094 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1095 RTX_FRAME_RELATED_P (push_rtx) = 1;
1096 offset = offset + 4;
1097 par_index++;
1098 /* Create (set mem gp). */
1099 reg = gen_rtx_REG (SImode, GP_REGNUM);
1100 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1101 stack_pointer_rtx,
1102 offset));
1103 push_rtx = gen_rtx_SET (mem, reg);
1104 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1105 RTX_FRAME_RELATED_P (push_rtx) = 1;
1106 offset = offset + 4;
1107 par_index++;
1108 /* Create (set mem lp). */
1109 reg = gen_rtx_REG (SImode, LP_REGNUM);
1110 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1111 stack_pointer_rtx,
1112 offset));
1113 push_rtx = gen_rtx_SET (mem, reg);
1114 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1115 RTX_FRAME_RELATED_P (push_rtx) = 1;
1116 offset = offset + 4;
1117 par_index++;
1119 /* Create (set sp sp-x-imm8u). */
1121 /* We need to re-calculate the offset value again for adjustment. */
1122 offset = -(num_use_regs * 4);
1123 adjust_sp_rtx
1124 = gen_rtx_SET (stack_pointer_rtx,
1125 plus_constant (Pmode,
1126 stack_pointer_rtx,
1127 offset - imm8u));
1128 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
1129 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
1131 parallel_insn = emit_insn (parallel_insn);
1133 /* The insn rtx 'parallel_insn' will change frame layout.
1134 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1135 generate CFI (Call Frame Information) stuff. */
1136 RTX_FRAME_RELATED_P (parallel_insn) = 1;
1139 /* Function to create a parallel rtx pattern
1140 which presents stack v3pop behavior.
1141 The overall concept are:
1142 "pop registers from memory",
1143 "adjust stack pointer". */
1144 static void
1145 nds32_emit_stack_v3pop (unsigned Rb,
1146 unsigned Re,
1147 unsigned imm8u)
1149 unsigned regno;
1150 int num_use_regs;
1151 int par_index;
1152 int offset;
1154 rtx reg;
1155 rtx mem;
1156 rtx pop_rtx;
1157 rtx adjust_sp_rtx;
1158 rtx parallel_insn;
1159 rtx dwarf = NULL_RTX;
1161 /* We need to provide a customized rtx which contains
1162 necessary information for data analysis,
1163 so we create a parallel rtx like this:
1164 (parallel [(set (reg:SI Rb)
1165 (mem (reg:SI SP_REGNUM)))
1166 (set (reg:SI Rb+1)
1167 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
1169 (set (reg:SI Re)
1170 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
1171 (set (reg:SI FP_REGNUM)
1172 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
1173 (set (reg:SI GP_REGNUM)
1174 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
1175 (set (reg:SI LP_REGNUM)
1176 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
1177 (set (reg:SI SP_REGNUM)
1178 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
1180 /* Calculate the number of registers that will be poped.
1181 Since $fp, $gp, and $lp is always poped with v3pop instruction,
1182 we need to count these three registers.
1183 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1184 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1185 num_use_regs = Re - Rb + 1 + 3;
1187 /* In addition to used registers,
1188 we need one more space for (set sp sp+x+imm8u) rtx. */
1189 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
1190 rtvec_alloc (num_use_regs + 1));
1191 par_index = 0;
1193 /* Initialize offset and start to create pop behavior. */
1194 offset = 0;
1196 /* Create (set regX mem) from Rb, Rb+1 up to Re.
1197 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1198 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1199 for (regno = Rb; regno <= Re; regno++)
1201 reg = gen_rtx_REG (SImode, regno);
1202 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1203 stack_pointer_rtx,
1204 offset));
1205 pop_rtx = gen_rtx_SET (reg, mem);
1206 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1207 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1208 offset = offset + 4;
1209 par_index++;
1211 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1214 /* Create (set fp mem). */
1215 reg = gen_rtx_REG (SImode, FP_REGNUM);
1216 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1217 stack_pointer_rtx,
1218 offset));
1219 pop_rtx = gen_rtx_SET (reg, mem);
1220 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1221 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1222 offset = offset + 4;
1223 par_index++;
1224 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1226 /* Create (set gp mem). */
1227 reg = gen_rtx_REG (SImode, GP_REGNUM);
1228 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1229 stack_pointer_rtx,
1230 offset));
1231 pop_rtx = gen_rtx_SET (reg, mem);
1232 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1233 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1234 offset = offset + 4;
1235 par_index++;
1236 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1238 /* Create (set lp mem ). */
1239 reg = gen_rtx_REG (SImode, LP_REGNUM);
1240 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1241 stack_pointer_rtx,
1242 offset));
1243 pop_rtx = gen_rtx_SET (reg, mem);
1244 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1245 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1246 offset = offset + 4;
1247 par_index++;
1248 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1250 /* Create (set sp sp+x+imm8u). */
1252 /* The offset value is already in place. No need to re-calculate it. */
1253 adjust_sp_rtx
1254 = gen_rtx_SET (stack_pointer_rtx,
1255 plus_constant (Pmode,
1256 stack_pointer_rtx,
1257 offset + imm8u));
1258 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
1260 if (frame_pointer_needed)
1262 /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp)
1263 (const_int 0))
1264 mean reset frame pointer to $sp and reset to offset 0. */
1265 rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1266 const0_rtx);
1267 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
1269 else
1271 /* Tell gcc we adjust SP in this insn. */
1272 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
1273 copy_rtx (adjust_sp_rtx), dwarf);
1276 parallel_insn = emit_insn (parallel_insn);
1278 /* The insn rtx 'parallel_insn' will change frame layout.
1279 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1280 generate CFI (Call Frame Information) stuff. */
1281 RTX_FRAME_RELATED_P (parallel_insn) = 1;
1283 /* Add CFI info by manual. */
1284 REG_NOTES (parallel_insn) = dwarf;
1287 static void
1288 nds32_emit_load_gp (void)
1290 rtx got_symbol, pat;
1292 /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
1293 emit_insn (gen_blockage ());
1295 got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1296 /* sethi $gp, _GLOBAL_OFFSET_TABLE_ -8 */
1297 pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT);
1298 pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-8)));
1299 emit_insn (gen_sethi (pic_offset_table_rtx,pat));
1301 /* ori $gp, $gp, _GLOBAL_OFFSET_TABLE_ -4 */
1302 pat = gen_rtx_UNSPEC (SImode, gen_rtvec (1, got_symbol), UNSPEC_GOTINIT);
1303 pat = gen_rtx_CONST (SImode, gen_rtx_PLUS (Pmode, pat, GEN_INT (-4)));
1304 emit_insn (gen_lo_sum (pic_offset_table_rtx, pic_offset_table_rtx, pat));
1306 /* add5.pc $gp */
1307 emit_insn (gen_add_pc (pic_offset_table_rtx, pic_offset_table_rtx));
1309 /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
1310 emit_insn (gen_blockage ());
1313 /* Function that may creates more instructions
1314 for large value on adjusting stack pointer.
1316 In nds32 target, 'addi' can be used for stack pointer
1317 adjustment in prologue/epilogue stage.
1318 However, sometimes there are too many local variables so that
1319 the adjustment value is not able to be fit in the 'addi' instruction.
1320 One solution is to move value into a register
1321 and then use 'add' instruction.
1322 In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */
1323 static void
1324 nds32_emit_adjust_frame (rtx to_reg, rtx from_reg, int adjust_value)
1326 rtx tmp_reg;
1327 rtx frame_adjust_insn;
1328 rtx adjust_value_rtx = GEN_INT (adjust_value);
1330 if (adjust_value == 0)
1331 return;
1333 if (!satisfies_constraint_Is15 (adjust_value_rtx))
1335 /* The value is not able to fit in single addi instruction.
1336 Create more instructions of moving value into a register
1337 and then add stack pointer with it. */
1339 /* $r15 is going to be temporary register to hold the value. */
1340 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1342 /* Create one more instruction to move value
1343 into the temporary register. */
1344 emit_move_insn (tmp_reg, adjust_value_rtx);
1346 /* Create new 'add' rtx. */
1347 frame_adjust_insn = gen_addsi3 (to_reg,
1348 from_reg,
1349 tmp_reg);
1350 /* Emit rtx into insn list and receive its transformed insn rtx. */
1351 frame_adjust_insn = emit_insn (frame_adjust_insn);
1353 /* Because (tmp_reg <- full_value) may be split into two
1354 rtl patterns, we cannot set its RTX_FRAME_RELATED_P.
1355 We need to construct another (sp <- sp + full_value)
1356 and then insert it into sp_adjust_insn's reg note to
1357 represent a frame related expression.
1358 GCC knows how to refer it and output debug information. */
1360 rtx plus_rtx;
1361 rtx set_rtx;
1363 plus_rtx = plus_constant (Pmode, from_reg, adjust_value);
1364 set_rtx = gen_rtx_SET (to_reg, plus_rtx);
1365 add_reg_note (frame_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
1367 else
1369 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
1370 frame_adjust_insn = gen_addsi3 (to_reg,
1371 from_reg,
1372 adjust_value_rtx);
1373 /* Emit rtx into instructions list and receive INSN rtx form. */
1374 frame_adjust_insn = emit_insn (frame_adjust_insn);
1377 /* The insn rtx 'sp_adjust_insn' will change frame layout.
1378 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1379 generate CFI (Call Frame Information) stuff. */
1380 RTX_FRAME_RELATED_P (frame_adjust_insn) = 1;
1383 /* Return true if MODE/TYPE need double word alignment. */
1384 static bool
1385 nds32_needs_double_word_align (machine_mode mode, const_tree type)
1387 unsigned int align;
1389 /* Pick up the alignment according to the mode or type. */
1390 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1392 return (align > PARM_BOUNDARY);
1395 /* Return true if FUNC is a naked function. */
1396 bool
1397 nds32_naked_function_p (tree func)
1399 /* FOR BACKWARD COMPATIBILITY,
1400 we need to support 'no_prologue' attribute as well. */
1401 tree t_naked;
1402 tree t_no_prologue;
1404 if (TREE_CODE (func) != FUNCTION_DECL)
1405 abort ();
1407 /* We have to use lookup_attribute() to check attributes.
1408 Because attr_naked_p and attr_no_prologue_p are set in
1409 nds32_compute_stack_frame() and the function has not been
1410 invoked yet. */
1411 t_naked = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1412 t_no_prologue = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (func));
1414 return ((t_naked != NULL_TREE) || (t_no_prologue != NULL_TREE));
1417 /* Function that determine whether a load postincrement is a good thing to use
1418 for a given mode. */
1419 bool
1420 nds32_use_load_post_increment (machine_mode mode)
1422 return (GET_MODE_SIZE (mode) <= GET_MODE_SIZE(E_DImode));
1425 /* Function that check if 'X' is a valid address register.
1426 The variable 'STRICT' is very important to
1427 make decision for register number.
1429 STRICT : true
1430 => We are in reload pass or after reload pass.
1431 The register number should be strictly limited in general registers.
1433 STRICT : false
1434 => Before reload pass, we are free to use any register number. */
1435 static bool
1436 nds32_address_register_rtx_p (rtx x, bool strict)
1438 int regno;
1440 if (GET_CODE (x) != REG)
1441 return false;
1443 regno = REGNO (x);
1445 if (strict)
1446 return REGNO_OK_FOR_BASE_P (regno);
1447 else
1448 return true;
1451 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1453 OUTER_MODE : Machine mode of outer address rtx.
1454 INDEX : Check if this rtx is valid to be a index for address.
1455 STRICT : If it is true, we are in reload pass or after reload pass. */
1456 static bool
1457 nds32_legitimate_index_p (machine_mode outer_mode,
1458 rtx index,
1459 bool strict)
1461 int regno;
1462 rtx op0;
1463 rtx op1;
1465 switch (GET_CODE (index))
1467 case REG:
1468 regno = REGNO (index);
1469 /* If we are in reload pass or after reload pass,
1470 we need to limit it to general register. */
1471 if (strict)
1472 return REGNO_OK_FOR_INDEX_P (regno);
1473 else
1474 return true;
1476 case CONST_INT:
1477 /* The alignment of the integer value is determined by 'outer_mode'. */
1478 switch (GET_MODE_SIZE (outer_mode))
1480 case 1:
1481 /* Further check if the value is legal for the 'outer_mode'. */
1482 if (satisfies_constraint_Is15 (index))
1483 return true;
1484 break;
1486 case 2:
1487 /* Further check if the value is legal for the 'outer_mode'. */
1488 if (satisfies_constraint_Is16 (index))
1490 /* If it is not under strictly aligned situation,
1491 we can return true without checking alignment. */
1492 if (!cfun->machine->strict_aligned_p)
1493 return true;
1494 /* Make sure address is half word alignment. */
1495 else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1496 return true;
1498 break;
1500 case 4:
1501 /* Further check if the value is legal for the 'outer_mode'. */
1502 if (satisfies_constraint_Is17 (index))
1504 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
1506 if (!satisfies_constraint_Is14 (index))
1507 return false;
1510 /* If it is not under strictly aligned situation,
1511 we can return true without checking alignment. */
1512 if (!cfun->machine->strict_aligned_p)
1513 return true;
1514 /* Make sure address is word alignment. */
1515 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1516 return true;
1518 break;
1520 case 8:
1521 if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1522 SImode)))
1524 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
1526 if (!satisfies_constraint_Is14 (index))
1527 return false;
1530 /* If it is not under strictly aligned situation,
1531 we can return true without checking alignment. */
1532 if (!cfun->machine->strict_aligned_p)
1533 return true;
1534 /* Make sure address is word alignment.
1535 Currently we do not have 64-bit load/store yet,
1536 so we will use two 32-bit load/store instructions to do
1537 memory access and they are single word alignment. */
1538 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1539 return true;
1541 break;
1543 default:
1544 return false;
1547 return false;
1549 case MULT:
1550 op0 = XEXP (index, 0);
1551 op1 = XEXP (index, 1);
1553 if (REG_P (op0) && CONST_INT_P (op1))
1555 int multiplier;
1556 multiplier = INTVAL (op1);
1558 /* We only allow (mult reg const_int_1), (mult reg const_int_2),
1559 (mult reg const_int_4) or (mult reg const_int_8). */
1560 if (multiplier != 1 && multiplier != 2
1561 && multiplier != 4 && multiplier != 8)
1562 return false;
1564 regno = REGNO (op0);
1565 /* Limit it in general registers if we are
1566 in reload pass or after reload pass. */
1567 if(strict)
1568 return REGNO_OK_FOR_INDEX_P (regno);
1569 else
1570 return true;
1573 return false;
1575 case ASHIFT:
1576 op0 = XEXP (index, 0);
1577 op1 = XEXP (index, 1);
1579 if (REG_P (op0) && CONST_INT_P (op1))
1581 int sv;
1582 /* op1 is already the sv value for use to do left shift. */
1583 sv = INTVAL (op1);
1585 /* We only allow (ashift reg const_int_0)
1586 or (ashift reg const_int_1) or (ashift reg const_int_2) or
1587 (ashift reg const_int_3). */
1588 if (sv != 0 && sv != 1 && sv !=2 && sv != 3)
1589 return false;
1591 regno = REGNO (op0);
1592 /* Limit it in general registers if we are
1593 in reload pass or after reload pass. */
1594 if(strict)
1595 return REGNO_OK_FOR_INDEX_P (regno);
1596 else
1597 return true;
1600 return false;
1602 default:
1603 return false;
1607 static void
1608 nds32_register_pass (
1609 rtl_opt_pass *(*make_pass_func) (gcc::context *),
1610 enum pass_positioning_ops pass_pos,
1611 const char *ref_pass_name)
1613 opt_pass *new_opt_pass = make_pass_func (g);
1615 struct register_pass_info insert_pass =
1617 new_opt_pass, /* pass */
1618 ref_pass_name, /* reference_pass_name */
1619 1, /* ref_pass_instance_number */
1620 pass_pos /* po_op */
1623 register_pass (&insert_pass);
1626 /* This function is called from nds32_option_override ().
1627 All new passes should be registered here. */
1628 static void
1629 nds32_register_passes (void)
1631 nds32_register_pass (
1632 make_pass_nds32_fp_as_gp,
1633 PASS_POS_INSERT_BEFORE,
1634 "ira");
1636 nds32_register_pass (
1637 make_pass_nds32_relax_opt,
1638 PASS_POS_INSERT_AFTER,
1639 "mach");
1642 /* ------------------------------------------------------------------------ */
1644 /* PART 3: Implement target hook stuff definitions. */
1647 /* Computing the Length of an Insn.
1648 Modifies the length assigned to instruction INSN.
1649 LEN is the initially computed length of the insn. */
1651 nds32_adjust_insn_length (rtx_insn *insn, int length)
1653 int adjust_value = 0;
1654 switch (recog_memoized (insn))
1656 case CODE_FOR_call_internal:
1657 case CODE_FOR_call_value_internal:
1659 if (NDS32_ALIGN_P ())
1661 rtx_insn *next_insn = next_active_insn (insn);
1662 if (next_insn && get_attr_length (next_insn) != 2)
1663 adjust_value += 2;
1665 /* We need insert a nop after a noretun function call
1666 to prevent software breakpoint corrupt the next function. */
1667 if (find_reg_note (insn, REG_NORETURN, NULL_RTX))
1669 if (TARGET_16_BIT)
1670 adjust_value += 2;
1671 else
1672 adjust_value += 4;
1675 return length + adjust_value;
1677 default:
1678 return length;
1682 /* Storage Layout. */
1684 /* This function will be called just before expansion into rtl. */
1685 static void
1686 nds32_expand_to_rtl_hook (void)
1688 /* We need to set strictly aligned situation.
1689 After that, the memory address checking in nds32_legitimate_address_p()
1690 will take alignment offset into consideration so that it will not create
1691 unaligned [base + offset] access during the rtl optimization. */
1692 cfun->machine->strict_aligned_p = 1;
1696 /* Register Usage. */
1698 static void
1699 nds32_conditional_register_usage (void)
1701 int regno;
1703 if (TARGET_LINUX_ABI)
1704 fixed_regs[TP_REGNUM] = 1;
1706 if (TARGET_HARD_FLOAT)
1708 for (regno = NDS32_FIRST_FPR_REGNUM;
1709 regno <= NDS32_LAST_FPR_REGNUM; regno++)
1711 fixed_regs[regno] = 0;
1712 if (regno < NDS32_FIRST_FPR_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS)
1713 call_used_regs[regno] = 1;
1714 else if (regno >= NDS32_FIRST_FPR_REGNUM + 22
1715 && regno < NDS32_FIRST_FPR_REGNUM + 48)
1716 call_used_regs[regno] = 1;
1717 else
1718 call_used_regs[regno] = 0;
1721 else if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
1723 for (regno = NDS32_FIRST_FPR_REGNUM;
1724 regno <= NDS32_LAST_FPR_REGNUM;
1725 regno++)
1726 fixed_regs[regno] = 0;
1731 /* Register Classes. */
1733 static unsigned char
1734 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1735 machine_mode mode)
1737 /* Return the maximum number of consecutive registers
1738 needed to represent "mode" in a register of "rclass". */
1739 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1742 static int
1743 nds32_register_priority (int hard_regno)
1745 /* Encourage to use r0-r7 for LRA when optimize for size. */
1746 if (optimize_size)
1748 if (hard_regno < 8)
1749 return 4;
1750 else if (hard_regno < 16)
1751 return 3;
1752 else if (hard_regno < 28)
1753 return 2;
1754 else
1755 return 1;
1757 else
1759 if (hard_regno > 27)
1760 return 1;
1761 else
1762 return 4;
1766 static bool
1767 nds32_can_change_mode_class (machine_mode from,
1768 machine_mode to,
1769 reg_class_t rclass)
1771 /* Don't spill double-precision register to two singal-precision
1772 registers */
1773 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
1774 && GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
1776 return !reg_classes_intersect_p (rclass, FP_REGS);
1779 return true;
1783 /* Stack Layout and Calling Conventions. */
1785 /* There are three kinds of pointer concepts using in GCC compiler:
1787 frame pointer: A pointer to the first location of local variables.
1788 stack pointer: A pointer to the top of a stack frame.
1789 argument pointer: A pointer to the incoming arguments.
1791 In nds32 target calling convention, we are using 8-byte alignment.
1792 Besides, we would like to have each stack frame of a function includes:
1794 [Block A]
1795 1. previous hard frame pointer
1796 2. return address
1797 3. callee-saved registers
1798 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1799 and save it at
1800 cfun->machine->callee_saved_area_padding_bytes)
1802 [Block B]
1803 1. local variables
1804 2. spilling location
1805 3. <padding bytes> (it will be calculated by GCC itself)
1806 4. incoming arguments
1807 5. <padding bytes> (it will be calculated by GCC itself)
1809 [Block C]
1810 1. <padding bytes> (it will be calculated by GCC itself)
1811 2. outgoing arguments
1813 We 'wrap' these blocks together with
1814 hard frame pointer ($r28) and stack pointer ($r31).
1815 By applying the basic frame/stack/argument pointers concept,
1816 the layout of a stack frame shoule be like this:
1819 old stack pointer -> ----
1820 | | \
1821 | | saved arguments for
1822 | | vararg functions
1823 | | /
1824 hard frame pointer -> --
1825 & argument pointer | | \
1826 | | previous hardware frame pointer
1827 | | return address
1828 | | callee-saved registers
1829 | | /
1830 frame pointer -> --
1831 | | \
1832 | | local variables
1833 | | and incoming arguments
1834 | | /
1836 | | \
1837 | | outgoing
1838 | | arguments
1839 | | /
1840 stack pointer -> ----
1842 $SFP and $AP are used to represent frame pointer and arguments pointer,
1843 which will be both eliminated as hard frame pointer. */
1845 /* -- Eliminating Frame Pointer and Arg Pointer. */
1847 static bool
1848 nds32_can_eliminate (const int from_reg, const int to_reg)
1850 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1851 return true;
1853 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1854 return true;
1856 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1857 return true;
1859 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1860 return true;
1862 return false;
1865 /* -- Passing Arguments in Registers. */
1867 static rtx
1868 nds32_function_arg (cumulative_args_t ca, const function_arg_info &arg)
1870 unsigned int regno;
1871 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1872 tree type = arg.type;
1873 machine_mode mode = arg.mode;
1875 /* The last time this hook is called,
1876 it is called with an end marker. */
1877 if (arg.end_marker_p ())
1878 return NULL_RTX;
1880 /* For nameless arguments, we need to take care it individually. */
1881 if (!arg.named)
1883 /* If we are under hard float abi, we have arguments passed on the
1884 stack and all situation can be handled by GCC itself. */
1885 if (TARGET_HARD_FLOAT)
1886 return NULL_RTX;
1888 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1890 /* If we still have enough registers to pass argument, pick up
1891 next available register number. */
1892 regno
1893 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1894 return gen_rtx_REG (mode, regno);
1897 /* No register available, return NULL_RTX.
1898 The compiler will use stack to pass argument instead. */
1899 return NULL_RTX;
1902 /* The following is to handle named argument.
1903 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1904 are different. */
1905 if (TARGET_HARD_FLOAT)
1907 /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR
1908 to pass argument. We have to further check TYPE and MODE so
1909 that we can determine which kind of register we shall use. */
1911 /* Note that we need to pass argument entirely in registers under
1912 hard float abi. */
1913 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1914 && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum->fpr_offset, mode, type))
1916 /* Pick up the next available FPR register number. */
1917 regno
1918 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type);
1919 return gen_rtx_REG (mode, regno);
1921 else if (GET_MODE_CLASS (mode) != MODE_FLOAT
1922 && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1924 /* Pick up the next available GPR register number. */
1925 regno
1926 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1927 return gen_rtx_REG (mode, regno);
1930 else
1932 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1933 argument. Since we allow to pass argument partially in registers,
1934 we can just return it if there are still registers available. */
1935 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1937 /* Pick up the next available register number. */
1938 regno
1939 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1940 return gen_rtx_REG (mode, regno);
1945 /* No register available, return NULL_RTX.
1946 The compiler will use stack to pass argument instead. */
1947 return NULL_RTX;
1950 static bool
1951 nds32_must_pass_in_stack (const function_arg_info &arg)
1953 /* Return true if a type must be passed in memory.
1954 If it is NOT using hard float abi, small aggregates can be
1955 passed in a register even we are calling a variadic function.
1956 So there is no need to take padding into consideration. */
1957 if (TARGET_HARD_FLOAT)
1958 return must_pass_in_stack_var_size_or_pad (arg);
1959 else
1960 return must_pass_in_stack_var_size (arg);
1963 static int
1964 nds32_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
1966 /* Returns the number of bytes at the beginning of an argument that
1967 must be put in registers. The value must be zero for arguments that are
1968 passed entirely in registers or that are entirely pushed on the stack.
1969 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1970 first register to be used by the caller for this argument. */
1971 unsigned int needed_reg_count;
1972 unsigned int remaining_reg_count;
1973 CUMULATIVE_ARGS *cum;
1975 cum = get_cumulative_args (ca);
1977 /* Under hard float abi, we better have argument entirely passed in
1978 registers or pushed on the stack so that we can reduce the complexity
1979 of dealing with cum->gpr_offset and cum->fpr_offset. */
1980 if (TARGET_HARD_FLOAT)
1981 return 0;
1983 /* If we have already runned out of argument registers, return zero
1984 so that the argument will be entirely pushed on the stack. */
1985 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
1986 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1987 return 0;
1989 /* Calculate how many registers do we need for this argument. */
1990 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
1992 /* Calculate how many argument registers have left for passing argument.
1993 Note that we should count it from next available register number. */
1994 remaining_reg_count
1995 = NDS32_MAX_GPR_REGS_FOR_ARGS
1996 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset,
1997 arg.mode, arg.type)
1998 - NDS32_GPR_ARG_FIRST_REGNUM);
2000 /* Note that we have to return the nubmer of bytes, not registers count. */
2001 if (needed_reg_count > remaining_reg_count)
2002 return remaining_reg_count * UNITS_PER_WORD;
2004 return 0;
2007 static void
2008 nds32_function_arg_advance (cumulative_args_t ca,
2009 const function_arg_info &arg)
2011 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
2012 tree type = arg.type;
2013 machine_mode mode = arg.mode;
2015 if (arg.named)
2017 /* We need to further check TYPE and MODE so that we can determine
2018 which kind of register we shall advance. */
2020 /* Under hard float abi, we may advance FPR registers. */
2021 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
2023 cum->fpr_offset
2024 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type)
2025 - NDS32_FPR_ARG_FIRST_REGNUM
2026 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
2028 else
2030 cum->gpr_offset
2031 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
2032 - NDS32_GPR_ARG_FIRST_REGNUM
2033 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
2036 else
2038 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
2039 we can advance next register as well so that caller is
2040 able to pass arguments in registers and callee must be
2041 in charge of pushing all of them into stack. */
2042 if (!TARGET_HARD_FLOAT)
2044 cum->gpr_offset
2045 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
2046 - NDS32_GPR_ARG_FIRST_REGNUM
2047 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
2052 static unsigned int
2053 nds32_function_arg_boundary (machine_mode mode, const_tree type)
2055 return (nds32_needs_double_word_align (mode, type)
2056 ? NDS32_DOUBLE_WORD_ALIGNMENT
2057 : PARM_BOUNDARY);
2060 bool
2061 nds32_vector_mode_supported_p (machine_mode mode)
2063 if (mode == V4QImode
2064 || mode == V2HImode)
2065 return NDS32_EXT_DSP_P ();
2067 return false;
2070 /* -- How Scalar Function Values Are Returned. */
2072 static rtx
2073 nds32_function_value (const_tree ret_type,
2074 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
2075 bool outgoing ATTRIBUTE_UNUSED)
2077 machine_mode mode;
2078 int unsignedp;
2080 mode = TYPE_MODE (ret_type);
2081 unsignedp = TYPE_UNSIGNED (ret_type);
2083 if (INTEGRAL_TYPE_P (ret_type))
2084 mode = promote_mode (ret_type, mode, &unsignedp);
2086 if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
2087 return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM);
2088 else
2089 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
2092 static rtx
2093 nds32_libcall_value (machine_mode mode,
2094 const_rtx fun ATTRIBUTE_UNUSED)
2096 if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
2097 return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM);
2099 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
2102 static bool
2103 nds32_function_value_regno_p (const unsigned int regno)
2105 if (regno == NDS32_GPR_RET_FIRST_REGNUM
2106 || (TARGET_HARD_FLOAT
2107 && regno == NDS32_FPR_RET_FIRST_REGNUM))
2108 return true;
2110 return false;
2113 /* -- How Large Values Are Returned. */
2115 static bool
2116 nds32_return_in_memory (const_tree type,
2117 const_tree fntype ATTRIBUTE_UNUSED)
2119 /* Note that int_size_in_bytes can return -1 if the size can vary
2120 or is larger than an integer. */
2121 HOST_WIDE_INT size = int_size_in_bytes (type);
2123 /* For COMPLEX_TYPE, if the total size cannot be hold within two registers,
2124 the return value is supposed to be in memory. We need to be aware of
2125 that the size may be -1. */
2126 if (TREE_CODE (type) == COMPLEX_TYPE)
2127 if (size < 0 || size > 2 * UNITS_PER_WORD)
2128 return true;
2130 /* If it is BLKmode and the total size cannot be hold within two registers,
2131 the return value is supposed to be in memory. We need to be aware of
2132 that the size may be -1. */
2133 if (TYPE_MODE (type) == BLKmode)
2134 if (size < 0 || size > 2 * UNITS_PER_WORD)
2135 return true;
2137 /* For other cases, having result in memory is unnecessary. */
2138 return false;
2141 /* -- Function Entry and Exit. */
2143 /* The content produced from this function
2144 will be placed before prologue body. */
2145 static void
2146 nds32_asm_function_prologue (FILE *file)
2148 int r;
2149 const char *func_name;
2150 tree attrs;
2151 tree name;
2153 /* All stack frame information is supposed to be
2154 already computed when expanding prologue.
2155 The result is in cfun->machine.
2156 DO NOT call nds32_compute_stack_frame() here
2157 because it may corrupt the essential information. */
2159 fprintf (file, "\t! BEGIN PROLOGUE\n");
2160 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
2161 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
2162 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
2163 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
2165 /* Use df_regs_ever_live_p() to detect if the register
2166 is ever used in the current function. */
2167 fprintf (file, "\t! registers ever_live: ");
2168 for (r = 0; r < 65; r++)
2170 if (df_regs_ever_live_p (r))
2171 fprintf (file, "%s, ", reg_names[r]);
2173 fputc ('\n', file);
2175 /* Display the attributes of this function. */
2176 fprintf (file, "\t! function attributes: ");
2177 /* Get the attributes tree list.
2178 Note that GCC builds attributes list with reverse order. */
2179 attrs = DECL_ATTRIBUTES (current_function_decl);
2181 /* If there is no any attribute, print out "None". */
2182 if (!attrs)
2183 fprintf (file, "None");
2185 /* If there are some attributes, try if we need to
2186 construct isr vector information. */
2187 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
2188 nds32_construct_isr_vectors_information (attrs, func_name);
2190 /* Display all attributes of this function. */
2191 while (attrs)
2193 name = TREE_PURPOSE (attrs);
2194 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
2196 /* Pick up the next attribute. */
2197 attrs = TREE_CHAIN (attrs);
2199 fputc ('\n', file);
2202 /* After rtl prologue has been expanded, this function is used. */
2203 static void
2204 nds32_asm_function_end_prologue (FILE *file)
2206 fprintf (file, "\t! END PROLOGUE\n");
2209 /* Before rtl epilogue has been expanded, this function is used. */
2210 static void
2211 nds32_asm_function_begin_epilogue (FILE *file)
2213 fprintf (file, "\t! BEGIN EPILOGUE\n");
2216 /* The content produced from this function
2217 will be placed after epilogue body. */
2218 static void
2219 nds32_asm_function_epilogue (FILE *file)
2221 fprintf (file, "\t! END EPILOGUE\n");
2224 static void
2225 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
2226 HOST_WIDE_INT delta,
2227 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
2228 tree function)
2230 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
2231 int this_regno;
2233 assemble_start_function (thunk, fnname);
2234 /* Make sure unwind info is emitted for the thunk if needed. */
2235 final_start_function (emit_barrier (), file, 1);
2237 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
2239 : 0);
2241 if (flag_pic)
2243 fprintf (file, "\tsmw.adm\t$r31, [$r31], $r31, 4\n");
2244 fprintf (file, "\tsethi\t%s, hi20(_GLOBAL_OFFSET_TABLE_-8)\n",
2245 reg_names [PIC_OFFSET_TABLE_REGNUM]);
2246 fprintf (file, "\tori\t%s, %s, lo12(_GLOBAL_OFFSET_TABLE_-4)\n",
2247 reg_names [PIC_OFFSET_TABLE_REGNUM],
2248 reg_names [PIC_OFFSET_TABLE_REGNUM]);
2250 if (TARGET_ISA_V3)
2251 fprintf (file, "\tadd5.pc\t$gp\n");
2252 else
2254 fprintf (file, "\tmfusr\t$ta, $pc\n");
2255 fprintf (file, "\tadd\t%s, $ta, %s\n",
2256 reg_names [PIC_OFFSET_TABLE_REGNUM],
2257 reg_names [PIC_OFFSET_TABLE_REGNUM]);
2261 if (delta != 0)
2263 if (satisfies_constraint_Is15 (GEN_INT (delta)))
2265 fprintf (file, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC "\n",
2266 this_regno, this_regno, delta);
2268 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
2270 fprintf (file, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC "\n", delta);
2271 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2273 else
2275 fprintf (file,
2276 "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC ")\n",
2277 delta);
2278 fprintf (file,
2279 "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC ")\n",
2280 delta);
2281 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2285 if (flag_pic)
2287 fprintf (file, "\tla\t$ta, ");
2288 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
2289 fprintf (file, "@PLT\n");
2290 fprintf (file, "\t! epilogue\n");
2291 fprintf (file, "\tlwi.bi\t%s, [%s], 4\n",
2292 reg_names[PIC_OFFSET_TABLE_REGNUM],
2293 reg_names[STACK_POINTER_REGNUM]);
2294 fprintf (file, "\tbr\t$ta\n");
2296 else
2298 fprintf (file, "\tb\t");
2299 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
2300 fprintf (file, "\n");
2303 final_end_function ();
2304 assemble_end_function (thunk, fnname);
2307 /* -- Permitting tail calls. */
2309 /* Return true if it is ok to do sibling call optimization. */
2310 static bool
2311 nds32_function_ok_for_sibcall (tree decl,
2312 tree exp ATTRIBUTE_UNUSED)
2314 /* The DECL is NULL if it is an indirect call. */
2316 /* 1. Do not apply sibling call if -mv3push is enabled,
2317 because pop25 instruction also represents return behavior.
2318 2. If this function is a isr function, do not apply sibling call
2319 because it may perform the behavior that user does not expect.
2320 3. If this function is a variadic function, do not apply sibling call
2321 because the stack layout may be a mess.
2322 4. We don't want to apply sibling call optimization for indirect
2323 sibcall because the pop behavior in epilogue may pollute the
2324 content of caller-saved regsiter when the register is used for
2325 indirect sibcall.
2326 5. In pic mode, it may use some registers for PLT call. */
2327 return (!TARGET_V3PUSH
2328 && !nds32_isr_function_p (current_function_decl)
2329 && (cfun->machine->va_args_size == 0)
2330 && decl
2331 && !flag_pic);
2334 /* Determine whether we need to enable warning for function return check. */
2335 static bool
2336 nds32_warn_func_return (tree decl)
2338 /* Naked functions are implemented entirely in assembly, including the
2339 return sequence, so suppress warnings about this. */
2340 return !nds32_naked_function_p (decl);
2344 /* Implementing the Varargs Macros. */
2346 static void
2347 nds32_setup_incoming_varargs (cumulative_args_t ca,
2348 const function_arg_info &arg,
2349 int *pretend_args_size,
2350 int second_time ATTRIBUTE_UNUSED)
2352 unsigned int total_args_regs;
2353 unsigned int num_of_used_regs;
2354 unsigned int remaining_reg_count;
2355 CUMULATIVE_ARGS *cum;
2357 /* If we are under hard float abi, we do not need to set *pretend_args_size.
2358 So that all nameless arguments are pushed by caller and all situation
2359 can be handled by GCC itself. */
2360 if (TARGET_HARD_FLOAT)
2361 return;
2363 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
2364 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
2365 However, for nameless(anonymous) arguments, we should push them on the
2366 stack so that all the nameless arguments appear to have been passed
2367 consecutively in the memory for accessing. Hence, we need to check and
2368 exclude the registers that are used for named arguments. */
2370 cum = get_cumulative_args (ca);
2372 /* ARG describes the last argument.
2373 We need those information to determine the remaining registers
2374 for varargs. */
2375 total_args_regs
2376 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
2377 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
2378 || arg.type != NULL_TREE)
2379 num_of_used_regs
2380 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, arg.mode, arg.type)
2381 + NDS32_NEED_N_REGS_FOR_ARG (arg.mode, arg.type);
2382 else
2383 num_of_used_regs = cum->gpr_offset + NDS32_GPR_ARG_FIRST_REGNUM;
2385 remaining_reg_count = total_args_regs - num_of_used_regs;
2386 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
2388 return;
2391 static bool
2392 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
2394 /* If this hook returns true, the named argument of FUNCTION_ARG is always
2395 true for named arguments, and false for unnamed arguments. */
2396 return true;
2400 /* Trampolines for Nested Functions. */
2402 static void
2403 nds32_asm_trampoline_template (FILE *f)
2405 if (TARGET_REDUCED_REGS)
2407 /* Trampoline is not supported on reduced-set registers yet. */
2408 sorry ("a nested function is not supported for reduced registers");
2410 else
2412 asm_fprintf (f, "\t! Trampoline code template\n");
2413 asm_fprintf (f, "\t! This code fragment will be copied "
2414 "into stack on demand\n");
2416 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
2417 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
2418 "! load nested function address\n");
2419 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
2420 "! load chain_value\n");
2421 asm_fprintf (f, "\tjr\t$r15\n");
2424 /* Preserve space ($pc + 16) for saving chain_value,
2425 nds32_trampoline_init will fill the value in this slot. */
2426 asm_fprintf (f, "\t! space for saving chain_value\n");
2427 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2429 /* Preserve space ($pc + 20) for saving nested function address,
2430 nds32_trampoline_init will fill the value in this slot. */
2431 asm_fprintf (f, "\t! space for saving nested function address\n");
2432 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2435 /* Emit RTL insns to initialize the variable parts of a trampoline. */
2436 static void
2437 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2439 int i;
2441 /* Nested function address. */
2442 rtx fnaddr;
2443 /* The memory rtx that is going to
2444 be filled with chain_value. */
2445 rtx chain_value_mem;
2446 /* The memory rtx that is going to
2447 be filled with nested function address. */
2448 rtx nested_func_mem;
2450 /* Start address of trampoline code in stack, for doing cache sync. */
2451 rtx sync_cache_addr;
2452 /* Temporary register for sync instruction. */
2453 rtx tmp_reg;
2454 /* Instruction-cache sync instruction,
2455 requesting an argument as starting address. */
2456 rtx isync_insn;
2457 /* For convenience reason of doing comparison. */
2458 int tramp_align_in_bytes;
2460 /* Trampoline is not supported on reduced-set registers yet. */
2461 if (TARGET_REDUCED_REGS)
2462 sorry ("a nested function is not supported for reduced registers");
2464 /* STEP 1: Copy trampoline code template into stack,
2465 fill up essential data into stack. */
2467 /* Extract nested function address rtx. */
2468 fnaddr = XEXP (DECL_RTL (fndecl), 0);
2470 /* m_tramp is memory rtx that is going to be filled with trampoline code.
2471 We have nds32_asm_trampoline_template() to emit template pattern. */
2472 emit_block_move (m_tramp, assemble_trampoline_template (),
2473 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2475 /* After copying trampoline code into stack,
2476 fill chain_value into stack. */
2477 chain_value_mem = adjust_address (m_tramp, SImode, 16);
2478 emit_move_insn (chain_value_mem, chain_value);
2479 /* After copying trampoline code int stack,
2480 fill nested function address into stack. */
2481 nested_func_mem = adjust_address (m_tramp, SImode, 20);
2482 emit_move_insn (nested_func_mem, fnaddr);
2484 /* STEP 2: Sync instruction-cache. */
2486 /* We have successfully filled trampoline code into stack.
2487 However, in order to execute code in stack correctly,
2488 we must sync instruction cache. */
2489 sync_cache_addr = XEXP (m_tramp, 0);
2490 tmp_reg = gen_reg_rtx (SImode);
2491 isync_insn = gen_unspec_volatile_isync (tmp_reg);
2493 /* Because nds32_cache_block_size is in bytes,
2494 we get trampoline alignment in bytes for convenient comparison. */
2495 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
2497 if (tramp_align_in_bytes >= nds32_cache_block_size
2498 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
2500 /* Under this condition, the starting address of trampoline
2501 must be aligned to the starting address of each cache block
2502 and we do not have to worry about cross-boundary issue. */
2503 for (i = 0;
2504 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2505 / nds32_cache_block_size;
2506 i++)
2508 emit_move_insn (tmp_reg,
2509 plus_constant (Pmode, sync_cache_addr,
2510 nds32_cache_block_size * i));
2511 emit_insn (isync_insn);
2514 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
2516 /* The starting address of trampoline code
2517 may not be aligned to the cache block,
2518 so the trampoline code may be across two cache block.
2519 We need to sync the last element, which is 4-byte size,
2520 of trampoline template. */
2521 for (i = 0;
2522 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2523 / nds32_cache_block_size;
2524 i++)
2526 emit_move_insn (tmp_reg,
2527 plus_constant (Pmode, sync_cache_addr,
2528 nds32_cache_block_size * i));
2529 emit_insn (isync_insn);
2532 /* The last element of trampoline template is 4-byte size. */
2533 emit_move_insn (tmp_reg,
2534 plus_constant (Pmode, sync_cache_addr,
2535 TRAMPOLINE_SIZE - 4));
2536 emit_insn (isync_insn);
2538 else
2540 /* This is the simplest case.
2541 Because TRAMPOLINE_SIZE is less than or
2542 equal to nds32_cache_block_size,
2543 we can just sync start address and
2544 the last element of trampoline code. */
2546 /* Sync starting address of tampoline code. */
2547 emit_move_insn (tmp_reg, sync_cache_addr);
2548 emit_insn (isync_insn);
2549 /* Sync the last element, which is 4-byte size,
2550 of trampoline template. */
2551 emit_move_insn (tmp_reg,
2552 plus_constant (Pmode, sync_cache_addr,
2553 TRAMPOLINE_SIZE - 4));
2554 emit_insn (isync_insn);
2557 /* Set instruction serialization barrier
2558 to guarantee the correct operations. */
2559 emit_insn (gen_unspec_volatile_isb ());
2563 /* Addressing Modes. */
2565 static bool
2566 nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict,
2567 code_helper = ERROR_MARK)
2569 if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
2571 /* When using floating-point instructions,
2572 we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */
2573 if ((mode == DFmode || mode == SFmode)
2574 && (GET_CODE (x) == SYMBOL_REF
2575 || GET_CODE(x) == CONST))
2576 return false;
2578 /* Allow [post_modify] addressing mode, when using FPU instructions. */
2579 if (GET_CODE (x) == POST_MODIFY
2580 && mode == DFmode)
2582 if (GET_CODE (XEXP (x, 0)) == REG
2583 && GET_CODE (XEXP (x, 1)) == PLUS)
2585 rtx plus_op = XEXP (x, 1);
2586 rtx op0 = XEXP (plus_op, 0);
2587 rtx op1 = XEXP (plus_op, 1);
2589 if (nds32_address_register_rtx_p (op0, strict)
2590 && CONST_INT_P (op1))
2592 if (satisfies_constraint_Is14 (op1))
2594 /* If it is not under strictly aligned situation,
2595 we can return true without checking alignment. */
2596 if (!cfun->machine->strict_aligned_p)
2597 return true;
2598 /* Make sure address is word alignment.
2599 Currently we do not have 64-bit load/store yet,
2600 so we will use two 32-bit load/store instructions to do
2601 memory access and they are single word alignment. */
2602 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1)))
2603 return true;
2610 /* For (mem:DI addr) or (mem:DF addr) case,
2611 we only allow 'addr' to be [reg], [symbol_ref],
2612 [const], or [reg + const_int] pattern. */
2613 if (mode == DImode || mode == DFmode)
2615 /* Allow [Reg + const_int] addressing mode. */
2616 if (GET_CODE (x) == PLUS)
2618 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2619 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
2620 && CONST_INT_P (XEXP (x, 1)))
2621 return true;
2622 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2623 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
2624 && CONST_INT_P (XEXP (x, 0)))
2625 return true;
2628 /* Allow [post_inc] and [post_dec] addressing mode. */
2629 if (GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC)
2631 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2632 return true;
2635 /* Now check [reg], [symbol_ref], and [const]. */
2636 if (GET_CODE (x) != REG
2637 && GET_CODE (x) != SYMBOL_REF
2638 && GET_CODE (x) != CONST)
2639 return false;
2642 /* Check if 'x' is a valid address. */
2643 switch (GET_CODE (x))
2645 case REG:
2646 /* (mem (reg A)) => [Ra] */
2647 return nds32_address_register_rtx_p (x, strict);
2649 case SYMBOL_REF:
2650 /* (mem (symbol_ref A)) => [symbol_ref] */
2652 if (flag_pic || SYMBOL_REF_TLS_MODEL (x))
2653 return false;
2655 if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x))
2656 return false;
2658 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
2659 during or after LRA/reload phase. */
2660 if (TARGET_CMODEL_LARGE
2661 && (reload_completed
2662 || reload_in_progress
2663 || lra_in_progress))
2664 return false;
2665 /* If -mcmodel=medium and the symbol references to rodata section,
2666 the 'symbol_ref' is not a valid address during or after
2667 LRA/reload phase. */
2668 if (TARGET_CMODEL_MEDIUM
2669 && (NDS32_SYMBOL_REF_RODATA_P (x)
2670 || CONSTANT_POOL_ADDRESS_P (x))
2671 && (reload_completed
2672 || reload_in_progress
2673 || lra_in_progress))
2674 return false;
2676 return true;
2678 case CONST:
2679 /* (mem (const (...)))
2680 => [ + const_addr ], where const_addr = symbol_ref + const_int */
2681 if (GET_CODE (XEXP (x, 0)) == PLUS)
2683 rtx plus_op = XEXP (x, 0);
2685 rtx op0 = XEXP (plus_op, 0);
2686 rtx op1 = XEXP (plus_op, 1);
2688 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
2690 /* Now we see the [ + const_addr ] pattern, but we need
2691 some further checking. */
2693 if (flag_pic || SYMBOL_REF_TLS_MODEL (op0))
2694 return false;
2696 /* If -mcmodel=large, the 'const_addr' is not a valid address
2697 during or after LRA/reload phase. */
2698 if (TARGET_CMODEL_LARGE
2699 && (reload_completed
2700 || reload_in_progress
2701 || lra_in_progress))
2702 return false;
2703 /* If -mcmodel=medium and the symbol references to rodata section,
2704 the 'const_addr' is not a valid address during or after
2705 LRA/reload phase. */
2706 if (TARGET_CMODEL_MEDIUM
2707 && NDS32_SYMBOL_REF_RODATA_P (op0)
2708 && (reload_completed
2709 || reload_in_progress
2710 || lra_in_progress))
2711 return false;
2713 /* At this point we can make sure 'const_addr' is a
2714 valid address. */
2715 return true;
2719 return false;
2721 case POST_MODIFY:
2722 /* (mem (post_modify (reg) (plus (reg) (reg))))
2723 => [Ra], Rb */
2724 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2725 => [Ra], const_int */
2726 if (GET_CODE (XEXP (x, 0)) == REG
2727 && GET_CODE (XEXP (x, 1)) == PLUS)
2729 rtx plus_op = XEXP (x, 1);
2731 rtx op0 = XEXP (plus_op, 0);
2732 rtx op1 = XEXP (plus_op, 1);
2734 if (nds32_address_register_rtx_p (op0, strict)
2735 && nds32_legitimate_index_p (mode, op1, strict))
2736 return true;
2737 else
2738 return false;
2741 return false;
2743 case POST_INC:
2744 case POST_DEC:
2745 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2746 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2747 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2748 We only need to deal with register Ra. */
2749 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2750 return true;
2751 else
2752 return false;
2754 case PLUS:
2755 /* (mem (plus reg const_int))
2756 => [Ra + imm] */
2757 /* (mem (plus reg reg))
2758 => [Ra + Rb] */
2759 /* (mem (plus (mult reg const_int) reg))
2760 => [Ra + Rb << sv] */
2761 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2762 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2763 return true;
2764 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2765 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2766 return true;
2767 else
2768 return false;
2770 case LO_SUM:
2771 /* (mem (lo_sum (reg) (symbol_ref))) */
2772 /* (mem (lo_sum (reg) (const (plus (symbol_ref) (reg)))) */
2773 /* TLS case: (mem (lo_sum (reg) (const (unspec symbol_ref X)))) */
2774 /* The LO_SUM is a valid address if and only if we would like to
2775 generate 32-bit full address memory access with any of following
2776 circumstance:
2777 1. -mcmodel=large.
2778 2. -mcmodel=medium and the symbol_ref references to rodata. */
2780 rtx sym = NULL_RTX;
2782 if (flag_pic)
2783 return false;
2785 if (!REG_P (XEXP (x, 0)))
2786 return false;
2788 if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
2789 sym = XEXP (x, 1);
2790 else if (GET_CODE (XEXP (x, 1)) == CONST)
2792 rtx plus = XEXP(XEXP (x, 1), 0);
2793 if (GET_CODE (plus) == PLUS)
2794 sym = XEXP (plus, 0);
2795 else if (GET_CODE (plus) == UNSPEC)
2796 sym = XVECEXP (plus, 0, 0);
2798 else
2799 return false;
2801 gcc_assert (GET_CODE (sym) == SYMBOL_REF);
2803 if (TARGET_ICT_MODEL_LARGE
2804 && nds32_indirect_call_referenced_p (sym))
2805 return true;
2807 if (TARGET_CMODEL_LARGE)
2808 return true;
2809 else if (TARGET_CMODEL_MEDIUM
2810 && NDS32_SYMBOL_REF_RODATA_P (sym))
2811 return true;
2812 else
2813 return false;
2816 default:
2817 return false;
2821 static rtx
2822 nds32_legitimize_address (rtx x,
2823 rtx oldx ATTRIBUTE_UNUSED,
2824 machine_mode mode ATTRIBUTE_UNUSED)
2826 if (nds32_tls_referenced_p (x))
2827 x = nds32_legitimize_tls_address (x);
2828 else if (flag_pic && SYMBOLIC_CONST_P (x))
2829 x = nds32_legitimize_pic_address (x);
2830 else if (TARGET_ICT_MODEL_LARGE && nds32_indirect_call_referenced_p (x))
2831 x = nds32_legitimize_ict_address (x);
2833 return x;
2836 static bool
2837 nds32_legitimate_constant_p (machine_mode mode, rtx x)
2839 switch (GET_CODE (x))
2841 case CONST_DOUBLE:
2842 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
2843 && (mode == DFmode || mode == SFmode))
2844 return false;
2845 break;
2846 case CONST:
2847 x = XEXP (x, 0);
2849 if (GET_CODE (x) == PLUS)
2851 if (!CONST_INT_P (XEXP (x, 1)))
2852 return false;
2853 x = XEXP (x, 0);
2856 if (GET_CODE (x) == UNSPEC)
2858 switch (XINT (x, 1))
2860 case UNSPEC_GOT:
2861 case UNSPEC_GOTOFF:
2862 case UNSPEC_PLT:
2863 case UNSPEC_TLSGD:
2864 case UNSPEC_TLSLD:
2865 case UNSPEC_TLSIE:
2866 case UNSPEC_TLSLE:
2867 case UNSPEC_ICT:
2868 return false;
2869 default:
2870 return true;
2873 break;
2874 case SYMBOL_REF:
2875 /* TLS symbols need a call to resolve in
2876 precompute_register_parameters. */
2877 if (SYMBOL_REF_TLS_MODEL (x))
2878 return false;
2879 break;
2880 default:
2881 return true;
2884 return true;
2887 /* Reorgnize the UNSPEC CONST and return its direct symbol. */
2888 static rtx
2889 nds32_delegitimize_address (rtx x)
2891 x = delegitimize_mem_from_attrs (x);
2893 if (GET_CODE(x) == CONST)
2895 rtx inner = XEXP (x, 0);
2897 /* Handle for GOTOFF. */
2898 if (GET_CODE (inner) == PLUS)
2899 inner = XEXP (inner, 0);
2901 if (GET_CODE (inner) == UNSPEC)
2903 switch (XINT (inner, 1))
2905 case UNSPEC_GOTINIT:
2906 case UNSPEC_GOT:
2907 case UNSPEC_GOTOFF:
2908 case UNSPEC_PLT:
2909 case UNSPEC_TLSGD:
2910 case UNSPEC_TLSLD:
2911 case UNSPEC_TLSIE:
2912 case UNSPEC_TLSLE:
2913 case UNSPEC_ICT:
2914 x = XVECEXP (inner, 0, 0);
2915 break;
2916 default:
2917 break;
2921 return x;
2924 static machine_mode
2925 nds32_vectorize_preferred_simd_mode (scalar_mode mode)
2927 if (!NDS32_EXT_DSP_P ())
2928 return word_mode;
2930 switch (mode)
2932 case E_QImode:
2933 return V4QImode;
2934 case E_HImode:
2935 return V2HImode;
2936 default:
2937 return word_mode;
2941 static bool
2942 nds32_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2944 switch (GET_CODE (x))
2946 case CONST:
2947 return !nds32_legitimate_constant_p (mode, x);
2948 case SYMBOL_REF:
2949 /* All symbols have to be accessed through gp-relative in PIC mode. */
2950 /* We don't want to force symbol as constant pool in .text section,
2951 because we use the gp-relatived instruction to load in small
2952 or medium model. */
2953 if (flag_pic
2954 || SYMBOL_REF_TLS_MODEL (x)
2955 || TARGET_CMODEL_SMALL
2956 || TARGET_CMODEL_MEDIUM)
2957 return true;
2958 break;
2959 case CONST_INT:
2960 case CONST_DOUBLE:
2961 if (flag_pic && (lra_in_progress || reload_completed))
2962 return true;
2963 break;
2964 default:
2965 return false;
2967 return false;
2971 /* Condition Code Status. */
2973 /* -- Representation of condition codes using registers. */
2975 static void
2976 nds32_canonicalize_comparison (int *code,
2977 rtx *op0 ATTRIBUTE_UNUSED,
2978 rtx *op1,
2979 bool op0_preserve_value ATTRIBUTE_UNUSED)
2981 /* When the instruction combination pass tries to combine a comparison insn
2982 with its previous insns, it also transforms the operator in order to
2983 minimize its constant field. For example, it tries to transform a
2984 comparison insn from
2985 (set (reg:SI 54)
2986 (ltu:SI (reg:SI 52)
2987 (const_int 10 [0xa])))
2989 (set (reg:SI 54)
2990 (leu:SI (reg:SI 52)
2991 (const_int 9 [0x9])))
2993 However, the nds32 target only provides instructions supporting the LTU
2994 operation directly, and the implementation of the pattern "cbranchsi4"
2995 only expands the LTU form. In order to handle the non-LTU operations
2996 generated from passes other than the RTL expansion pass, we have to
2997 implement this hook to revert those changes. Since we only expand the LTU
2998 operator in the RTL expansion pass, we might only need to handle the LEU
2999 case, unless we find other optimization passes perform more aggressive
3000 transformations. */
3002 if (*code == LEU && CONST_INT_P (*op1))
3004 *op1 = gen_int_mode (INTVAL (*op1) + 1, SImode);
3005 *code = LTU;
3010 /* Describing Relative Costs of Operations. */
3012 static int
3013 nds32_register_move_cost (machine_mode mode,
3014 reg_class_t from,
3015 reg_class_t to)
3017 /* In garywolf cpu, FPR to GPR is chaper than other cpu. */
3018 if (TARGET_PIPELINE_GRAYWOLF)
3020 if (GET_MODE_SIZE (mode) == 8)
3022 /* DPR to GPR. */
3023 if (from == FP_REGS && to != FP_REGS)
3024 return 3;
3025 /* GPR to DPR. */
3026 if (from != FP_REGS && to == FP_REGS)
3027 return 2;
3029 else
3031 if ((from == FP_REGS && to != FP_REGS)
3032 || (from != FP_REGS && to == FP_REGS))
3033 return 2;
3037 if ((from == FP_REGS && to != FP_REGS)
3038 || (from != FP_REGS && to == FP_REGS))
3039 return 3;
3040 else if (from == HIGH_REGS || to == HIGH_REGS)
3041 return optimize_size ? 6 : 2;
3042 else
3043 return 2;
3046 static int
3047 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3048 reg_class_t rclass ATTRIBUTE_UNUSED,
3049 bool in ATTRIBUTE_UNUSED)
3051 return 8;
3054 /* This target hook describes the relative costs of RTL expressions.
3055 Return 'true' when all subexpressions of x have been processed.
3056 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
3057 Refer to gcc/rtlanal.cc for more information. */
3058 static bool
3059 nds32_rtx_costs (rtx x,
3060 machine_mode mode,
3061 int outer_code,
3062 int opno,
3063 int *total,
3064 bool speed)
3066 return nds32_rtx_costs_impl (x, mode, outer_code, opno, total, speed);
3069 static int
3070 nds32_address_cost (rtx address,
3071 machine_mode mode,
3072 addr_space_t as,
3073 bool speed)
3075 return nds32_address_cost_impl (address, mode, as, speed);
3079 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3081 /* If references to a symbol or a constant must be treated differently
3082 depending on something about the variable or function named by the symbol
3083 (such as what section it is in), we use this hook to store flags
3084 in symbol_ref rtx. */
3085 static void
3086 nds32_encode_section_info (tree decl, rtx rtl, int new_decl_p)
3088 default_encode_section_info (decl, rtl, new_decl_p);
3090 /* For the memory rtx, if it references to rodata section, we can store
3091 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
3092 nds32_legitimate_address_p() can determine how to treat such symbol_ref
3093 based on -mcmodel=X and this information. */
3094 if (MEM_P (rtl) && MEM_READONLY_P (rtl))
3096 rtx addr = XEXP (rtl, 0);
3098 if (GET_CODE (addr) == SYMBOL_REF)
3100 /* For (mem (symbol_ref X)) case. */
3101 SYMBOL_REF_FLAGS (addr) |= NDS32_SYMBOL_FLAG_RODATA;
3103 else if (GET_CODE (addr) == CONST
3104 && GET_CODE (XEXP (addr, 0)) == PLUS)
3106 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
3107 rtx plus_op = XEXP (addr, 0);
3108 rtx op0 = XEXP (plus_op, 0);
3109 rtx op1 = XEXP (plus_op, 1);
3111 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
3112 SYMBOL_REF_FLAGS (op0) |= NDS32_SYMBOL_FLAG_RODATA;
3118 /* Defining the Output Assembler Language. */
3120 /* -- The Overall Framework of an Assembler File. */
3122 static void
3123 nds32_asm_file_start (void)
3125 default_file_start ();
3127 if (flag_pic)
3128 fprintf (asm_out_file, "\t.pic\n");
3130 /* Tell assembler which ABI we are using. */
3131 fprintf (asm_out_file, "\t! ABI version\n");
3132 if (TARGET_HARD_FLOAT)
3133 fprintf (asm_out_file, "\t.abi_2fp_plus\n");
3134 else
3135 fprintf (asm_out_file, "\t.abi_2\n");
3137 /* Tell assembler that this asm code is generated by compiler. */
3138 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
3139 fprintf (asm_out_file, "\t.flag\tverbatim\n");
3141 /* Insert directive for linker to distinguish object's ict flag. */
3142 if (!TARGET_LINUX_ABI)
3144 if (TARGET_ICT_MODEL_LARGE)
3145 fprintf (asm_out_file, "\t.ict_model\tlarge\n");
3146 else
3147 fprintf (asm_out_file, "\t.ict_model\tsmall\n");
3150 /* We need to provide the size of each vector for interrupt handler
3151 under elf toolchain. */
3152 if (!TARGET_LINUX_ABI)
3154 fprintf (asm_out_file, "\t! This vector size directive is required "
3155 "for checking inconsistency on interrupt handler\n");
3156 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
3159 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
3160 the compiler may produce 'la $fp,_FP_BASE_' instruction
3161 at prologue for fp-as-gp optimization.
3162 We should emit weak reference of _FP_BASE_ to avoid undefined reference
3163 in case user does not pass '--relax' option to linker. */
3164 if (!TARGET_LINUX_ABI && (TARGET_FORCE_FP_AS_GP || optimize_size))
3166 fprintf (asm_out_file, "\t! This weak reference is required to do "
3167 "fp-as-gp link time optimization\n");
3168 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
3171 fprintf (asm_out_file, "\t! ------------------------------------\n");
3173 if (TARGET_ISA_V2)
3174 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
3175 if (TARGET_ISA_V3)
3176 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
3177 if (TARGET_ISA_V3M)
3178 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
3180 switch (nds32_cpu_option)
3182 case CPU_N6:
3183 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N6");
3184 break;
3186 case CPU_N7:
3187 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N7");
3188 break;
3190 case CPU_N8:
3191 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N8");
3192 break;
3194 case CPU_E8:
3195 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "E8");
3196 break;
3198 case CPU_N9:
3199 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N9");
3200 break;
3202 case CPU_N10:
3203 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N10");
3204 break;
3206 case CPU_GRAYWOLF:
3207 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "Graywolf");
3208 break;
3210 case CPU_N12:
3211 case CPU_N13:
3212 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "N13");
3213 break;
3215 case CPU_SIMPLE:
3216 fprintf (asm_out_file, "\t! Pipeline model\t: %s\n", "SIMPLE");
3217 break;
3219 default:
3220 gcc_unreachable ();
3223 if (TARGET_CMODEL_SMALL)
3224 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL");
3225 if (TARGET_CMODEL_MEDIUM)
3226 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "MEDIUM");
3227 if (TARGET_CMODEL_LARGE)
3228 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "LARGE");
3230 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
3231 ((TARGET_BIG_ENDIAN) ? "big-endian"
3232 : "little-endian"));
3233 fprintf (asm_out_file, "\t! Use SP floating-point instruction\t: %s\n",
3234 ((TARGET_FPU_SINGLE) ? "Yes"
3235 : "No"));
3236 fprintf (asm_out_file, "\t! Use DP floating-point instruction\t: %s\n",
3237 ((TARGET_FPU_DOUBLE) ? "Yes"
3238 : "No"));
3239 fprintf (asm_out_file, "\t! ABI version\t\t: %s\n",
3240 ((TARGET_HARD_FLOAT) ? "ABI2FP+"
3241 : "ABI2"));
3243 fprintf (asm_out_file, "\t! ------------------------------------\n");
3245 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
3246 ((TARGET_CMOV) ? "Yes"
3247 : "No"));
3248 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
3249 ((TARGET_EXT_PERF) ? "Yes"
3250 : "No"));
3251 fprintf (asm_out_file, "\t! Use performance extension 2\t: %s\n",
3252 ((TARGET_EXT_PERF2) ? "Yes"
3253 : "No"));
3254 fprintf (asm_out_file, "\t! Use string extension\t\t: %s\n",
3255 ((TARGET_EXT_STRING) ? "Yes"
3256 : "No"));
3258 fprintf (asm_out_file, "\t! ------------------------------------\n");
3260 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
3261 ((TARGET_V3PUSH) ? "Yes"
3262 : "No"));
3263 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
3264 ((TARGET_16_BIT) ? "Yes"
3265 : "No"));
3266 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
3267 ((TARGET_REDUCED_REGS) ? "Yes"
3268 : "No"));
3270 fprintf (asm_out_file, "\t! Support unaligned access\t\t: %s\n",
3271 (flag_unaligned_access ? "Yes"
3272 : "No"));
3274 fprintf (asm_out_file, "\t! ------------------------------------\n");
3276 if (optimize_size)
3277 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
3278 else if (optimize_fast)
3279 fprintf (asm_out_file, "\t! Optimization level\t: -Ofast\n");
3280 else if (optimize_debug)
3281 fprintf (asm_out_file, "\t! Optimization level\t: -Og\n");
3282 else
3283 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
3285 fprintf (asm_out_file, "\t! ------------------------------------\n");
3287 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
3288 nds32_cache_block_size);
3290 fprintf (asm_out_file, "\t! ------------------------------------\n");
3292 nds32_asm_file_start_for_isr ();
3295 static void
3296 nds32_asm_file_end (void)
3298 nds32_asm_file_end_for_isr ();
3300 /* The NDS32 Linux stack is mapped non-executable by default, so add a
3301 .note.GNU-stack section. */
3302 if (TARGET_LINUX_ABI)
3303 file_end_indicate_exec_stack ();
3305 fprintf (asm_out_file, "\t! ------------------------------------\n");
3308 static bool
3309 nds32_asm_output_addr_const_extra (FILE *file, rtx x)
3311 if (GET_CODE (x) == UNSPEC)
3313 switch (XINT (x, 1))
3315 case UNSPEC_GOTINIT:
3316 output_addr_const (file, XVECEXP (x, 0, 0));
3317 break;
3318 case UNSPEC_GOTOFF:
3319 output_addr_const (file, XVECEXP (x, 0, 0));
3320 fputs ("@GOTOFF", file);
3321 break;
3322 case UNSPEC_GOT:
3323 output_addr_const (file, XVECEXP (x, 0, 0));
3324 fputs ("@GOT", file);
3325 break;
3326 case UNSPEC_PLT:
3327 output_addr_const (file, XVECEXP (x, 0, 0));
3328 fputs ("@PLT", file);
3329 break;
3330 case UNSPEC_TLSGD:
3331 output_addr_const (file, XVECEXP (x, 0, 0));
3332 fputs ("@TLSDESC", file);
3333 break;
3334 case UNSPEC_TLSLD:
3335 output_addr_const (file, XVECEXP (x, 0, 0));
3336 fputs ("@TLSDESC", file);
3337 break;
3338 case UNSPEC_TLSIE:
3339 output_addr_const (file, XVECEXP (x, 0, 0));
3340 fputs ("@GOTTPOFF", file);
3341 break;
3342 case UNSPEC_TLSLE:
3343 output_addr_const (file, XVECEXP (x, 0, 0));
3344 fputs ("@TPOFF", file);
3345 break;
3346 case UNSPEC_ICT:
3347 output_addr_const (file, XVECEXP (x, 0, 0));
3348 fputs ("@ICT", file);
3349 break;
3350 default:
3351 return false;
3353 return true;
3355 else
3356 return false;
3359 /* -- Output and Generation of Labels. */
3361 static void
3362 nds32_asm_globalize_label (FILE *stream, const char *name)
3364 fputs ("\t.global\t", stream);
3365 assemble_name (stream, name);
3366 fputs ("\n", stream);
3369 /* -- Output of Assembler Instructions. */
3371 static void
3372 nds32_print_operand (FILE *stream, rtx x, int code)
3374 HOST_WIDE_INT op_value = 0;
3375 HOST_WIDE_INT one_position;
3376 HOST_WIDE_INT zero_position;
3377 bool pick_lsb_p = false;
3378 bool pick_msb_p = false;
3379 int regno;
3381 if (CONST_INT_P (x))
3382 op_value = INTVAL (x);
3384 switch (code)
3386 case 0 :
3387 /* Do nothing special. */
3388 break;
3390 case 'b':
3391 /* Use exact_log2() to search the 0-bit position. */
3392 gcc_assert (CONST_INT_P (x));
3393 zero_position = exact_log2 (~UINTVAL (x) & GET_MODE_MASK (SImode));
3394 gcc_assert (zero_position != -1);
3395 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, zero_position);
3397 /* No need to handle following process, so return immediately. */
3398 return;
3400 case 'e':
3401 gcc_assert (MEM_P (x)
3402 && GET_CODE (XEXP (x, 0)) == PLUS
3403 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
3404 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (XEXP (x, 0), 1)));
3406 /* No need to handle following process, so return immediately. */
3407 return;
3409 case 'v':
3410 gcc_assert (CONST_INT_P (x)
3411 && (INTVAL (x) == 0
3412 || INTVAL (x) == 8
3413 || INTVAL (x) == 16
3414 || INTVAL (x) == 24));
3415 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
3417 /* No need to handle following process, so return immediately. */
3418 return;
3420 case 'B':
3421 /* Use exact_log2() to search the 1-bit position. */
3422 gcc_assert (CONST_INT_P (x));
3423 one_position = exact_log2 (UINTVAL (x) & GET_MODE_MASK (SImode));
3424 gcc_assert (one_position != -1);
3425 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, one_position);
3427 /* No need to handle following process, so return immediately. */
3428 return;
3430 case 'L':
3431 /* X is supposed to be REG rtx. */
3432 gcc_assert (REG_P (x));
3433 /* Claim that we are going to pick LSB part of X. */
3434 pick_lsb_p = true;
3435 break;
3437 case 'H':
3438 /* X is supposed to be REG rtx. */
3439 gcc_assert (REG_P (x));
3440 /* Claim that we are going to pick MSB part of X. */
3441 pick_msb_p = true;
3442 break;
3444 case 'V':
3445 /* 'x' is supposed to be CONST_INT, get the value. */
3446 gcc_assert (CONST_INT_P (x));
3448 /* According to the Andes architecture,
3449 the system/user register index range is 0 ~ 1023.
3450 In order to avoid conflict between user-specified-integer value
3451 and enum-specified-register value,
3452 the 'enum nds32_intrinsic_registers' value
3453 in nds32_intrinsic.h starts from 1024. */
3454 if (op_value < 1024 && op_value >= 0)
3456 /* If user gives integer value directly (0~1023),
3457 we just print out the value. */
3458 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, op_value);
3460 else if (op_value < 0
3461 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
3462 + 1024))
3464 /* The enum index value for array size is out of range. */
3465 error ("intrinsic register index is out of range");
3467 else
3469 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3470 we can print out register name. Remember to substract 1024. */
3471 fprintf (stream, "%s",
3472 nds32_intrinsic_register_names[op_value - 1024]);
3475 /* No need to handle following process, so return immediately. */
3476 return;
3478 case 'R': /* cctl valck */
3479 /* Note the cctl divide to 5 group and share the same name table. */
3480 if (op_value < 0 || op_value > 4)
3481 error ("CCTL intrinsic function subtype out of range");
3482 fprintf (stream, "%s", nds32_cctl_names[op_value]);
3483 return;
3485 case 'T': /* cctl idxwbinv */
3486 /* Note the cctl divide to 5 group and share the same name table. */
3487 if (op_value < 0 || op_value > 4)
3488 error ("CCTL intrinsic function subtype out of range");
3489 fprintf (stream, "%s", nds32_cctl_names[op_value + 4]);
3490 return;
3492 case 'U': /* cctl vawbinv */
3493 /* Note the cctl divide to 5 group and share the same name table. */
3494 if (op_value < 0 || op_value > 4)
3495 error ("CCTL intrinsic function subtype out of range");
3496 fprintf (stream, "%s", nds32_cctl_names[op_value + 8]);
3497 return;
3499 case 'X': /* cctl idxread */
3500 /* Note the cctl divide to 5 group and share the same name table. */
3501 if (op_value < 0 || op_value > 4)
3502 error ("CCTL intrinsic function subtype out of range");
3503 fprintf (stream, "%s", nds32_cctl_names[op_value + 12]);
3504 return;
3506 case 'W': /* cctl idxwitre */
3507 /* Note the cctl divide to 5 group and share the same name table. */
3508 if (op_value < 0 || op_value > 4)
3509 error ("CCTL intrinsic function subtype out of range");
3510 fprintf (stream, "%s", nds32_cctl_names[op_value + 16]);
3511 return;
3513 case 'Z': /* dpref */
3514 fprintf (stream, "%s", nds32_dpref_names[op_value]);
3515 return;
3517 default :
3518 /* Unknown flag. */
3519 output_operand_lossage ("invalid operand output code");
3520 break;
3523 switch (GET_CODE (x))
3525 case LABEL_REF:
3526 output_addr_const (stream, x);
3527 break;
3529 case SYMBOL_REF:
3530 output_addr_const (stream, x);
3532 if (!TARGET_LINUX_ABI && nds32_indirect_call_referenced_p (x))
3533 fprintf (stream, "@ICT");
3535 break;
3537 case REG:
3538 /* Print a Double-precision register name. */
3539 if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
3540 && NDS32_IS_FPR_REGNUM (REGNO (x)))
3542 regno = REGNO (x);
3543 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno))
3545 output_operand_lossage ("invalid operand for code '%c'", code);
3546 break;
3548 fprintf (stream, "$fd%d", (regno - NDS32_FIRST_FPR_REGNUM) >> 1);
3549 break;
3552 /* Print LSB or MSB part of register pair if the
3553 constraint modifier 'L' or 'H' is specified. */
3554 if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
3555 && NDS32_IS_GPR_REGNUM (REGNO (x)))
3557 if ((pick_lsb_p && WORDS_BIG_ENDIAN)
3558 || (pick_msb_p && !WORDS_BIG_ENDIAN))
3560 /* If we would like to print out LSB register under big-endian,
3561 or print out MSB register under little-endian, we need to
3562 increase register number. */
3563 regno = REGNO (x);
3564 regno++;
3565 fputs (reg_names[regno], stream);
3566 break;
3570 /* Forbid using static chain register ($r16)
3571 on reduced-set registers configuration. */
3572 if (TARGET_REDUCED_REGS
3573 && REGNO (x) == STATIC_CHAIN_REGNUM)
3574 sorry ("a nested function is not supported for reduced registers");
3576 /* Normal cases, print out register name. */
3577 fputs (reg_names[REGNO (x)], stream);
3578 break;
3580 case MEM:
3581 output_address (GET_MODE (x), XEXP (x, 0));
3582 break;
3584 case HIGH:
3585 if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE)
3587 const REAL_VALUE_TYPE *rv;
3588 long val;
3589 gcc_assert (GET_MODE (x) == SFmode);
3591 rv = CONST_DOUBLE_REAL_VALUE (XEXP (x, 0));
3592 REAL_VALUE_TO_TARGET_SINGLE (*rv, val);
3594 fprintf (stream, "hi20(0x%lx)", val);
3596 else
3597 gcc_unreachable ();
3598 break;
3600 case CONST_DOUBLE:
3601 const REAL_VALUE_TYPE *rv;
3602 long val;
3603 gcc_assert (GET_MODE (x) == SFmode);
3605 rv = CONST_DOUBLE_REAL_VALUE (x);
3606 REAL_VALUE_TO_TARGET_SINGLE (*rv, val);
3608 fprintf (stream, "0x%lx", val);
3609 break;
3611 case CODE_LABEL:
3612 case CONST_INT:
3613 case CONST:
3614 output_addr_const (stream, x);
3615 break;
3617 case CONST_VECTOR:
3618 fprintf (stream, HOST_WIDE_INT_PRINT_HEX, const_vector_to_hwint (x));
3619 break;
3621 case LO_SUM:
3622 /* This is a special case for inline assembly using memory address 'p'.
3623 The inline assembly code is expected to use pesudo instruction
3624 for the operand. EX: la */
3625 output_addr_const (stream, XEXP(x, 1));
3626 break;
3628 default:
3629 /* Generally, output_addr_const () is able to handle most cases.
3630 We want to see what CODE could appear,
3631 so we use gcc_unreachable() to stop it. */
3632 debug_rtx (x);
3633 gcc_unreachable ();
3634 break;
3638 static void
3639 nds32_print_operand_address (FILE *stream,
3640 machine_mode mode ATTRIBUTE_UNUSED,
3641 rtx x)
3643 rtx op0, op1;
3645 switch (GET_CODE (x))
3647 case SYMBOL_REF:
3648 case CONST:
3649 /* [ + symbol_ref] */
3650 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3651 fputs ("[ + ", stream);
3652 output_addr_const (stream, x);
3653 fputs ("]", stream);
3654 break;
3656 case LO_SUM:
3657 /* This is a special case for inline assembly using memory operand 'm'.
3658 The inline assembly code is expected to use pesudo instruction
3659 for the operand. EX: [ls].[bhw] */
3660 fputs ("[ + ", stream);
3661 op1 = XEXP (x, 1);
3662 output_addr_const (stream, op1);
3663 fputs ("]", stream);
3664 break;
3666 case REG:
3667 /* Forbid using static chain register ($r16)
3668 on reduced-set registers configuration. */
3669 if (TARGET_REDUCED_REGS
3670 && REGNO (x) == STATIC_CHAIN_REGNUM)
3671 sorry ("a nested function is not supported for reduced registers");
3673 /* [Ra] */
3674 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
3675 break;
3677 case PLUS:
3678 op0 = XEXP (x, 0);
3679 op1 = XEXP (x, 1);
3681 /* Checking op0, forbid using static chain register ($r16)
3682 on reduced-set registers configuration. */
3683 if (TARGET_REDUCED_REGS
3684 && REG_P (op0)
3685 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3686 sorry ("a nested function is not supported for reduced registers");
3687 /* Checking op1, forbid using static chain register ($r16)
3688 on reduced-set registers configuration. */
3689 if (TARGET_REDUCED_REGS
3690 && REG_P (op1)
3691 && REGNO (op1) == STATIC_CHAIN_REGNUM)
3692 sorry ("a nested function is not supported for reduced registers");
3694 if (REG_P (op0) && CONST_INT_P (op1))
3696 /* [Ra + imm] */
3697 fprintf (stream, "[%s + (" HOST_WIDE_INT_PRINT_DEC ")]",
3698 reg_names[REGNO (op0)], INTVAL (op1));
3700 else if (REG_P (op0) && REG_P (op1))
3702 /* [Ra + Rb] */
3703 fprintf (stream, "[%s + %s]",
3704 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
3706 else if (GET_CODE (op0) == MULT && REG_P (op1))
3708 /* [Ra + Rb << sv]
3709 From observation, the pattern looks like:
3710 (plus:SI (mult:SI (reg:SI 58)
3711 (const_int 4 [0x4]))
3712 (reg/f:SI 57)) */
3713 int sv;
3715 /* We need to set sv to output shift value. */
3716 if (INTVAL (XEXP (op0, 1)) == 1)
3717 sv = 0;
3718 else if (INTVAL (XEXP (op0, 1)) == 2)
3719 sv = 1;
3720 else if (INTVAL (XEXP (op0, 1)) == 4)
3721 sv = 2;
3722 else if (INTVAL (XEXP (op0, 1)) == 8)
3723 sv = 3;
3724 else
3725 gcc_unreachable ();
3727 fprintf (stream, "[%s + %s << %d]",
3728 reg_names[REGNO (op1)],
3729 reg_names[REGNO (XEXP (op0, 0))],
3730 sv);
3732 else if (GET_CODE (op0) == ASHIFT && REG_P (op1))
3734 /* [Ra + Rb << sv]
3735 In normal, ASHIFT can be converted to MULT like above case.
3736 But when the address rtx does not go through canonicalize_address
3737 defined in fwprop, we'll need this case. */
3738 int sv = INTVAL (XEXP (op0, 1));
3739 gcc_assert (sv <= 3 && sv >=0);
3741 fprintf (stream, "[%s + %s << %d]",
3742 reg_names[REGNO (op1)],
3743 reg_names[REGNO (XEXP (op0, 0))],
3744 sv);
3746 else
3748 /* The control flow is not supposed to be here. */
3749 debug_rtx (x);
3750 gcc_unreachable ();
3753 break;
3755 case POST_MODIFY:
3756 /* (post_modify (regA) (plus (regA) (regB)))
3757 (post_modify (regA) (plus (regA) (const_int)))
3758 We would like to extract
3759 regA and regB (or const_int) from plus rtx. */
3760 op0 = XEXP (XEXP (x, 1), 0);
3761 op1 = XEXP (XEXP (x, 1), 1);
3763 /* Checking op0, forbid using static chain register ($r16)
3764 on reduced-set registers configuration. */
3765 if (TARGET_REDUCED_REGS
3766 && REG_P (op0)
3767 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3768 sorry ("a nested function is not supported for reduced registers");
3769 /* Checking op1, forbid using static chain register ($r16)
3770 on reduced-set registers configuration. */
3771 if (TARGET_REDUCED_REGS
3772 && REG_P (op1)
3773 && REGNO (op1) == STATIC_CHAIN_REGNUM)
3774 sorry ("a nested function is not supported for reduced registers");
3776 if (REG_P (op0) && REG_P (op1))
3778 /* [Ra], Rb */
3779 fprintf (stream, "[%s], %s",
3780 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
3782 else if (REG_P (op0) && CONST_INT_P (op1))
3784 /* [Ra], imm */
3785 fprintf (stream, "[%s], " HOST_WIDE_INT_PRINT_DEC,
3786 reg_names[REGNO (op0)], INTVAL (op1));
3788 else
3790 /* The control flow is not supposed to be here. */
3791 debug_rtx (x);
3792 gcc_unreachable ();
3795 break;
3797 case POST_INC:
3798 case POST_DEC:
3799 op0 = XEXP (x, 0);
3801 /* Checking op0, forbid using static chain register ($r16)
3802 on reduced-set registers configuration. */
3803 if (TARGET_REDUCED_REGS
3804 && REG_P (op0)
3805 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3806 sorry ("a nested function is not supported for reduced registers");
3808 if (REG_P (op0))
3810 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3811 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3812 We only need to deal with register Ra. */
3813 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
3815 else
3817 /* The control flow is not supposed to be here. */
3818 debug_rtx (x);
3819 gcc_unreachable ();
3822 break;
3824 default :
3825 /* Generally, output_addr_const () is able to handle most cases.
3826 We want to see what CODE could appear,
3827 so we use gcc_unreachable() to stop it. */
3828 debug_rtx (x);
3829 gcc_unreachable ();
3830 break;
3834 /* -- Assembler Commands for Exception Regions. */
3836 static rtx
3837 nds32_dwarf_register_span (rtx reg)
3839 rtx dwarf_high, dwarf_low;
3840 rtx dwarf_single;
3841 machine_mode mode;
3842 int regno;
3844 mode = GET_MODE (reg);
3845 regno = REGNO (reg);
3847 /* We need to adjust dwarf register information for floating-point registers
3848 rather than using default register number mapping. */
3849 if (regno >= NDS32_FIRST_FPR_REGNUM
3850 && regno <= NDS32_LAST_FPR_REGNUM)
3852 if (mode == DFmode || mode == SCmode)
3854 /* By default, GCC maps increasing register numbers to increasing
3855 memory locations, but paired FPRs in NDS32 target are always
3856 big-endian, i.e.:
3858 fd0 : fs0 fs1
3859 (MSB) (LSB)
3861 We must return parallel rtx to represent such layout. */
3862 dwarf_high = gen_rtx_REG (word_mode, regno);
3863 dwarf_low = gen_rtx_REG (word_mode, regno + 1);
3864 return gen_rtx_PARALLEL (VOIDmode,
3865 gen_rtvec (2, dwarf_low, dwarf_high));
3867 else if (mode == DCmode)
3869 rtx dwarf_high_re = gen_rtx_REG (word_mode, regno);
3870 rtx dwarf_low_re = gen_rtx_REG (word_mode, regno + 1);
3871 rtx dwarf_high_im = gen_rtx_REG (word_mode, regno);
3872 rtx dwarf_low_im = gen_rtx_REG (word_mode, regno + 1);
3873 return gen_rtx_PARALLEL (VOIDmode,
3874 gen_rtvec (4, dwarf_low_re, dwarf_high_re,
3875 dwarf_high_im, dwarf_low_im));
3877 else if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3879 return NULL_RTX;
3881 else
3883 /* We should not be here. */
3884 gcc_unreachable ();
3888 return NULL_RTX;
3891 /* Map internal gcc register numbers to DWARF2 register numbers. */
3893 unsigned int
3894 nds32_debugger_regno (unsigned int regno)
3896 /* The nds32 port in GDB maintains a mapping between dwarf register
3897 number and displayed register name. For backward compatibility to
3898 previous toolchain, currently our gdb still has four registers
3899 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3900 does not count those four registers in its register number table.
3901 So we have to add 4 on its register number and then create new
3902 dwarf information. Hopefully we can discard such workaround
3903 in the future. */
3904 if (NDS32_IS_FPR_REGNUM (regno))
3905 return regno + 4;
3907 return regno;
3911 /* Defining target-specific uses of __attribute__. */
3913 /* Add some checking after merging attributes. */
3914 static tree
3915 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
3917 tree combined_attrs;
3919 /* Create combined attributes. */
3920 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
3921 DECL_ATTRIBUTES (newdecl));
3923 /* Since newdecl is acutally a duplicate of olddecl,
3924 we can take olddecl for some operations. */
3925 if (TREE_CODE (olddecl) == FUNCTION_DECL)
3927 /* Check isr-specific attributes conflict. */
3928 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
3931 return combined_attrs;
3934 /* Add some checking when inserting attributes. */
3935 static void
3936 nds32_insert_attributes (tree decl, tree *attributes)
3938 /* A "indirect_call" function attribute implies "noinline" and "noclone"
3939 for elf toolchain to support ROM patch mechanism. */
3940 if (TREE_CODE (decl) == FUNCTION_DECL
3941 && lookup_attribute ("indirect_call", *attributes) != NULL)
3943 tree new_attrs = *attributes;
3945 if (TARGET_LINUX_ABI)
3946 error ("cannot use %<indirect_call%> attribute under linux toolchain");
3948 if (lookup_attribute ("noinline", new_attrs) == NULL)
3949 new_attrs = tree_cons (get_identifier ("noinline"), NULL, new_attrs);
3950 if (lookup_attribute ("noclone", new_attrs) == NULL)
3951 new_attrs = tree_cons (get_identifier ("noclone"), NULL, new_attrs);
3953 if (!TREE_PUBLIC (decl))
3954 error ("%<indirect_call%> attribute cannot apply for static function");
3956 *attributes = new_attrs;
3959 /* For function declaration, we need to check isr-specific attributes:
3960 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3961 2. Check valid integer value for interrupt/exception.
3962 3. Check valid integer value for reset.
3963 4. Check valid function for nmi/warm. */
3964 if (TREE_CODE (decl) == FUNCTION_DECL)
3966 tree func_attrs;
3967 tree intr, excp, reset;
3969 /* Pick up function attributes. */
3970 func_attrs = *attributes;
3972 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3973 nds32_check_isr_attrs_conflict (decl, func_attrs);
3975 /* Now we are starting to check valid id value
3976 for interrupt/exception/reset.
3977 Note that we ONLY check its validity here.
3978 To construct isr vector information, it is still performed
3979 by nds32_construct_isr_vectors_information(). */
3980 intr = lookup_attribute ("interrupt", func_attrs);
3981 excp = lookup_attribute ("exception", func_attrs);
3982 reset = lookup_attribute ("reset", func_attrs);
3984 /* The following code may use attribute arguments. If there is no
3985 argument from source code, it will cause segmentation fault.
3986 Therefore, return dircetly and report error message later. */
3987 if ((intr && TREE_VALUE (intr) == NULL)
3988 || (excp && TREE_VALUE (excp) == NULL)
3989 || (reset && TREE_VALUE (reset) == NULL))
3990 return;
3992 /* ------------------------------------------------------------- */
3993 /* FIXME:
3994 FOR BACKWARD COMPATIBILITY, we need to support following patterns:
3996 __attribute__((interrupt("XXX;YYY;id=ZZZ")))
3997 __attribute__((exception("XXX;YYY;id=ZZZ")))
3998 __attribute__((reset("vectors=XXX;nmi_func=YYY;warm_func=ZZZ")))
4000 If interrupt/exception/reset appears and its argument is a
4001 STRING_CST, we will use other functions to parse string in the
4002 nds32_construct_isr_vectors_information() and then set necessary
4003 isr information in the nds32_isr_vectors[] array. Here we can
4004 just return immediately to avoid new-syntax checking. */
4005 if (intr != NULL_TREE
4006 && TREE_CODE (TREE_VALUE (TREE_VALUE (intr))) == STRING_CST)
4007 return;
4008 if (excp != NULL_TREE
4009 && TREE_CODE (TREE_VALUE (TREE_VALUE (excp))) == STRING_CST)
4010 return;
4011 if (reset != NULL_TREE
4012 && TREE_CODE (TREE_VALUE (TREE_VALUE (reset))) == STRING_CST)
4013 return;
4014 /* ------------------------------------------------------------- */
4016 if (intr || excp)
4018 /* Deal with interrupt/exception. */
4019 tree id_list;
4020 unsigned int lower_bound, upper_bound;
4022 /* The way to handle interrupt or exception is the same,
4023 we just need to take care of actual vector number.
4024 For interrupt(0..63), the actual vector number is (9..72).
4025 For exception(1..8), the actual vector number is (1..8). */
4026 lower_bound = (intr) ? (0) : (1);
4027 upper_bound = (intr) ? (63) : (8);
4029 /* Prepare id list so that we can traverse id value. */
4030 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
4032 /* 2. Check valid integer value for interrupt/exception. */
4033 while (id_list)
4035 tree id;
4037 /* Pick up each vector id value. */
4038 id = TREE_VALUE (id_list);
4039 /* Issue error if it is not a valid integer value. */
4040 if (TREE_CODE (id) != INTEGER_CST
4041 || wi::ltu_p (wi::to_wide (id), lower_bound)
4042 || wi::gtu_p (wi::to_wide (id), upper_bound))
4043 error ("invalid id value for interrupt/exception attribute");
4045 /* Advance to next id. */
4046 id_list = TREE_CHAIN (id_list);
4049 else if (reset)
4051 /* Deal with reset. */
4052 tree id_list;
4053 tree id;
4054 tree nmi, warm;
4055 unsigned int lower_bound;
4056 unsigned int upper_bound;
4058 /* Prepare id_list and identify id value so that
4059 we can check if total number of vectors is valid. */
4060 id_list = TREE_VALUE (reset);
4061 id = TREE_VALUE (id_list);
4063 /* The maximum numbers for user's interrupt is 64. */
4064 lower_bound = 0;
4065 upper_bound = 64;
4067 /* 3. Check valid integer value for reset. */
4068 if (TREE_CODE (id) != INTEGER_CST
4069 || wi::ltu_p (wi::to_wide (id), lower_bound)
4070 || wi::gtu_p (wi::to_wide (id), upper_bound))
4071 error ("invalid id value for reset attribute");
4073 /* 4. Check valid function for nmi/warm. */
4074 nmi = lookup_attribute ("nmi", func_attrs);
4075 warm = lookup_attribute ("warm", func_attrs);
4077 if (nmi != NULL_TREE)
4079 tree nmi_func_list;
4080 tree nmi_func;
4082 nmi_func_list = TREE_VALUE (nmi);
4083 nmi_func = TREE_VALUE (nmi_func_list);
4085 /* Issue error if it is not a valid nmi function. */
4086 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
4087 error ("invalid nmi function for reset attribute");
4090 if (warm != NULL_TREE)
4092 tree warm_func_list;
4093 tree warm_func;
4095 warm_func_list = TREE_VALUE (warm);
4096 warm_func = TREE_VALUE (warm_func_list);
4098 /* Issue error if it is not a valid warm function. */
4099 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
4100 error ("invalid warm function for reset attribute");
4103 else
4105 /* No interrupt, exception, or reset attribute is set. */
4106 return;
4111 static bool
4112 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
4113 tree pop_target ATTRIBUTE_UNUSED)
4115 /* Currently, we do not parse any pragma target by ourself,
4116 so just simply return false. */
4117 return false;
4120 static void
4121 nds32_option_override (void)
4123 /* After all the command options have been parsed,
4124 we shall deal with some flags for changing compiler settings. */
4126 /* At first, we check if we have to strictly
4127 set some flags based on ISA family. */
4128 if (TARGET_ISA_V2)
4130 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
4131 target_flags &= ~MASK_V3PUSH;
4133 if (TARGET_ISA_V3)
4135 /* If this is ARCH_V3J, we need to enable TARGET_REDUCED_REGS. */
4136 if (nds32_arch_option == ARCH_V3J)
4137 target_flags |= MASK_REDUCED_REGS;
4139 if (TARGET_ISA_V3M)
4141 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
4142 target_flags |= MASK_REDUCED_REGS;
4143 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
4144 target_flags &= ~MASK_EXT_PERF;
4145 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
4146 target_flags &= ~MASK_EXT_PERF2;
4147 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
4148 target_flags &= ~MASK_EXT_STRING;
4150 if (flag_pic)
4151 error ("not support %<-fpic%> option for v3m toolchain");
4154 /* See if we are using reduced-set registers:
4155 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
4156 If so, we must forbid using $r11~$r14, $r16~$r27. */
4157 if (TARGET_REDUCED_REGS)
4159 int r;
4161 /* Prevent register allocator from
4162 choosing it as doing register allocation. */
4163 for (r = 11; r <= 14; r++)
4164 fixed_regs[r] = call_used_regs[r] = 1;
4165 for (r = 16; r <= 27; r++)
4166 fixed_regs[r] = call_used_regs[r] = 1;
4169 /* See if user explicitly would like to use fp-as-gp optimization.
4170 If so, we must prevent $fp from being allocated
4171 during register allocation. */
4172 if (TARGET_FORCE_FP_AS_GP)
4173 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
4175 if (!TARGET_16_BIT)
4177 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
4178 target_flags &= ~MASK_V3PUSH;
4181 if (TARGET_HARD_FLOAT && !(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
4183 if (nds32_arch_option == ARCH_V3S || nds32_arch_option == ARCH_V3F)
4184 error ("Disable FPU ISA, "
4185 "the ABI option must be enable %<-mfloat-abi=soft%>");
4186 else
4187 error ("%<-mabi=2fp+%> option only support when FPU available, "
4188 "must be enable %<-mext-fpu-sp%> or %<-mext-fpu-dp%>");
4191 nds32_init_rtx_costs ();
4193 nds32_register_passes ();
4197 /* Miscellaneous Parameters. */
4199 static rtx_insn *
4200 nds32_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
4201 vec<rtx> &inputs ATTRIBUTE_UNUSED,
4202 vec<machine_mode> &input_modes ATTRIBUTE_UNUSED,
4203 vec<const char *> &constraints ATTRIBUTE_UNUSED,
4204 vec<rtx> &/*uses*/, vec<rtx> &clobbers,
4205 HARD_REG_SET &clobbered_regs, location_t /*loc*/)
4207 if (!flag_inline_asm_r15)
4209 clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM));
4210 SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM);
4212 return NULL;
4215 static void
4216 nds32_init_builtins (void)
4218 nds32_init_builtins_impl ();
4221 static tree
4222 nds32_builtin_decl (unsigned code, bool initialize_p)
4224 /* Implement in nds32-intrinsic.cc. */
4225 return nds32_builtin_decl_impl (code, initialize_p);
4228 static rtx
4229 nds32_expand_builtin (tree exp,
4230 rtx target,
4231 rtx subtarget,
4232 machine_mode mode,
4233 int ignore)
4235 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
4238 /* Implement TARGET_INIT_LIBFUNCS. */
4239 static void
4240 nds32_init_libfuncs (void)
4242 if (TARGET_LINUX_ABI)
4243 init_sync_libfuncs (UNITS_PER_WORD);
4246 /* ------------------------------------------------------------------------ */
4248 /* PART 4: Implemet extern function definitions,
4249 the prototype is in nds32-protos.h. */
4251 /* Run-time Target Specification. */
4253 void
4254 nds32_cpu_cpp_builtins(struct cpp_reader *pfile)
4256 #define builtin_define(TXT) cpp_define (pfile, TXT)
4257 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
4258 builtin_define ("__nds32__");
4259 builtin_define ("__NDS32__");
4261 /* We need to provide builtin macro to describe the size of
4262 each vector for interrupt handler under elf toolchain. */
4263 if (!TARGET_LINUX_ABI)
4265 if (TARGET_ISR_VECTOR_SIZE_4_BYTE)
4266 builtin_define ("__NDS32_ISR_VECTOR_SIZE_4__");
4267 else
4268 builtin_define ("__NDS32_ISR_VECTOR_SIZE_16__");
4271 if (TARGET_HARD_FLOAT)
4272 builtin_define ("__NDS32_ABI_2FP_PLUS__");
4273 else
4274 builtin_define ("__NDS32_ABI_2__");
4276 if (TARGET_ISA_V2)
4277 builtin_define ("__NDS32_ISA_V2__");
4278 if (TARGET_ISA_V3)
4279 builtin_define ("__NDS32_ISA_V3__");
4280 if (TARGET_ISA_V3M)
4281 builtin_define ("__NDS32_ISA_V3M__");
4283 if (TARGET_FPU_SINGLE)
4284 builtin_define ("__NDS32_EXT_FPU_SP__");
4285 if (TARGET_FPU_DOUBLE)
4286 builtin_define ("__NDS32_EXT_FPU_DP__");
4288 if (TARGET_EXT_FPU_FMA)
4289 builtin_define ("__NDS32_EXT_FPU_FMA__");
4290 if (NDS32_EXT_FPU_DOT_E)
4291 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
4292 if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
4294 switch (nds32_fp_regnum)
4296 case 0:
4297 case 4:
4298 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
4299 break;
4300 case 1:
4301 case 5:
4302 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
4303 break;
4304 case 2:
4305 case 6:
4306 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
4307 break;
4308 case 3:
4309 case 7:
4310 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
4311 break;
4312 default:
4313 abort ();
4317 if (TARGET_BIG_ENDIAN)
4318 builtin_define ("__NDS32_EB__");
4319 else
4320 builtin_define ("__NDS32_EL__");
4322 if (TARGET_REDUCED_REGS)
4323 builtin_define ("__NDS32_REDUCED_REGS__");
4324 if (TARGET_CMOV)
4325 builtin_define ("__NDS32_CMOV__");
4326 if (TARGET_EXT_PERF)
4327 builtin_define ("__NDS32_EXT_PERF__");
4328 if (TARGET_EXT_PERF2)
4329 builtin_define ("__NDS32_EXT_PERF2__");
4330 if (TARGET_EXT_STRING)
4331 builtin_define ("__NDS32_EXT_STRING__");
4332 if (TARGET_16_BIT)
4333 builtin_define ("__NDS32_16_BIT__");
4334 if (TARGET_GP_DIRECT)
4335 builtin_define ("__NDS32_GP_DIRECT__");
4336 if (TARGET_VH)
4337 builtin_define ("__NDS32_VH__");
4338 if (NDS32_EXT_DSP_P ())
4339 builtin_define ("__NDS32_EXT_DSP__");
4341 if (TARGET_BIG_ENDIAN)
4342 builtin_define ("__big_endian__");
4344 builtin_assert ("cpu=nds32");
4345 builtin_assert ("machine=nds32");
4347 if (TARGET_HARD_FLOAT)
4348 builtin_define ("__NDS32_ABI_2FP_PLUS");
4349 else
4350 builtin_define ("__NDS32_ABI_2");
4352 #undef builtin_define
4353 #undef builtin_assert
4357 /* Defining Data Structures for Per-function Information. */
4359 void
4360 nds32_init_expanders (void)
4362 /* Arrange to initialize and mark the machine per-function status. */
4363 init_machine_status = nds32_init_machine_status;
4367 /* Register Usage. */
4369 /* -- Order of Allocation of Registers. */
4371 void
4372 nds32_adjust_reg_alloc_order (void)
4374 const int nds32_reg_alloc_order[] = REG_ALLOC_ORDER;
4376 /* Copy the default register allocation order, which is designed
4377 to optimize for code size. */
4378 memcpy(reg_alloc_order, nds32_reg_alloc_order, sizeof (reg_alloc_order));
4380 /* Adjust few register allocation order when optimizing for speed. */
4381 if (!optimize_size)
4383 memcpy (reg_alloc_order, nds32_reg_alloc_order_for_speed,
4384 sizeof (nds32_reg_alloc_order_for_speed));
4388 /* -- How Values Fit in Registers. */
4390 static unsigned
4391 nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED,
4392 machine_mode mode)
4394 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
4397 /* Implement TARGET_HARD_REGNO_MODE_OK. */
4399 static bool
4400 nds32_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
4402 if (regno >= FIRST_PSEUDO_REGISTER)
4403 return true;
4405 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) && NDS32_IS_FPR_REGNUM (regno))
4407 if (NDS32_IS_EXT_FPR_REGNUM(regno))
4408 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno) && (mode == DFmode));
4409 else if (mode == SFmode || mode == SImode)
4410 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno);
4411 else if (mode == DFmode)
4412 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno);
4414 return false;
4417 /* Restrict double-word quantities to even register pairs. */
4418 if (regno <= NDS32_LAST_GPR_REGNUM)
4419 return (targetm.hard_regno_nregs (regno, mode) == 1
4420 || !((regno) & 1));
4422 return false;
4425 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
4426 tie QI/HI/SI modes together. */
4428 static bool
4429 nds32_modes_tieable_p (machine_mode mode1, machine_mode mode2)
4431 if ((GET_MODE_CLASS (mode1) == MODE_INT
4432 && GET_MODE_CLASS (mode2) == MODE_INT)
4433 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
4434 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD)
4435 return true;
4437 if (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2))
4439 if ((TARGET_FPU_SINGLE && !TARGET_FPU_DOUBLE)
4440 && (mode1 == DFmode || mode2 == DFmode))
4441 return false;
4442 else
4443 return true;
4446 return false;
4449 /* Register Classes. */
4451 enum reg_class
4452 nds32_regno_reg_class (int regno)
4454 /* Refer to nds32.h for more register class details. */
4456 if (regno >= 0 && regno <= 7)
4457 return LOW_REGS;
4458 else if (regno >= 8 && regno <= 11)
4459 return MIDDLE_REGS;
4460 else if (regno >= 12 && regno <= 14)
4461 return HIGH_REGS;
4462 else if (regno == 15)
4463 return R15_TA_REG;
4464 else if (regno >= 16 && regno <= 19)
4465 return MIDDLE_REGS;
4466 else if (regno >= 20 && regno <= 31)
4467 return HIGH_REGS;
4468 else if (regno == 32 || regno == 33)
4470 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
4471 know how to allocate register for $SFP and $AP, just tell IRA they
4472 are GENERAL_REGS, and ARM do this hack too. */
4473 return GENERAL_REGS;
4475 else if (regno >= 34 && regno <= 97)
4476 return FP_REGS;
4477 else
4478 return NO_REGS;
4482 /* Stack Layout and Calling Conventions. */
4484 /* -- Basic Stack Layout. */
4487 nds32_dynamic_chain_address (rtx frameaddr)
4489 if (TARGET_V3PUSH)
4491 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
4492 We can access dynamic chain address from stack by [$fp - 12]. */
4493 return plus_constant (Pmode, frameaddr, -12);
4495 else
4497 /* For general case we push $fp and $lp into stack at prologue.
4498 We can access dynamic chain address from stack by [$fp - 8]. */
4499 return plus_constant (Pmode, frameaddr, -8);
4504 nds32_return_addr_rtx (int count,
4505 rtx frameaddr)
4507 int offset;
4508 rtx addr;
4510 if (count != 0)
4512 /* In nds32 ABI design, we can expect that $lp is always available
4513 from stack by [$fp - 4] location. */
4514 offset = -4;
4515 addr = plus_constant (Pmode, frameaddr, offset);
4516 addr = memory_address (Pmode, addr);
4518 return gen_rtx_MEM (Pmode, addr);
4521 /* If count == 0, it means we are at current frame,
4522 the return address is $r30 ($lp). */
4523 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
4526 /* -- Eliminating Frame Pointer and Arg Pointer. */
4528 HOST_WIDE_INT
4529 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
4531 HOST_WIDE_INT offset;
4533 /* Compute and setup stack frame size.
4534 The result will be in cfun->machine. */
4535 nds32_compute_stack_frame ();
4537 /* Remember to consider
4538 cfun->machine->callee_saved_area_gpr_padding_bytes and
4539 cfun->machine->eh_return_data_regs_size
4540 when calculating offset. */
4541 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
4543 offset = (cfun->machine->fp_size
4544 + cfun->machine->gp_size
4545 + cfun->machine->lp_size
4546 + cfun->machine->callee_saved_gpr_regs_size
4547 + cfun->machine->callee_saved_area_gpr_padding_bytes
4548 + cfun->machine->callee_saved_fpr_regs_size
4549 + cfun->machine->eh_return_data_regs_size
4550 + cfun->machine->local_size
4551 + cfun->machine->out_args_size);
4553 else if (from_reg == ARG_POINTER_REGNUM
4554 && to_reg == HARD_FRAME_POINTER_REGNUM)
4556 offset = 0;
4558 else if (from_reg == FRAME_POINTER_REGNUM
4559 && to_reg == STACK_POINTER_REGNUM)
4561 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
4563 else if (from_reg == FRAME_POINTER_REGNUM
4564 && to_reg == HARD_FRAME_POINTER_REGNUM)
4566 offset = (-1) * (cfun->machine->fp_size
4567 + cfun->machine->gp_size
4568 + cfun->machine->lp_size
4569 + cfun->machine->callee_saved_gpr_regs_size
4570 + cfun->machine->callee_saved_area_gpr_padding_bytes
4571 + cfun->machine->callee_saved_fpr_regs_size
4572 + cfun->machine->eh_return_data_regs_size);
4574 else
4576 gcc_unreachable ();
4579 return offset;
4582 /* -- Passing Arguments in Registers. */
4584 void
4585 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
4586 tree fntype ATTRIBUTE_UNUSED,
4587 rtx libname ATTRIBUTE_UNUSED,
4588 tree fndecl ATTRIBUTE_UNUSED,
4589 int n_named_args ATTRIBUTE_UNUSED)
4591 /* Initial available registers. The values are offset against
4592 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
4593 for passing arguments. */
4594 cum->gpr_offset = 0;
4595 cum->fpr_offset = 0;
4598 /* -- Function Entry and Exit. */
4600 /* Function for normal multiple push prologue. */
4601 void
4602 nds32_expand_prologue (void)
4604 int fp_adjust;
4605 int sp_adjust;
4606 unsigned Rb, Re;
4608 /* Compute and setup stack frame size.
4609 The result will be in cfun->machine. */
4610 nds32_compute_stack_frame ();
4612 /* Check frame_pointer_needed again to prevent fp is need after reload. */
4613 if (frame_pointer_needed)
4614 cfun->machine->fp_as_gp_p = false;
4616 /* If this is a variadic function, first we need to push argument
4617 registers that hold the unnamed argument value. */
4618 if (cfun->machine->va_args_size != 0)
4620 Rb = cfun->machine->va_args_first_regno;
4621 Re = cfun->machine->va_args_last_regno;
4622 /* No need to push $fp, $gp, or $lp. */
4623 nds32_emit_stack_push_multiple (Rb, Re, false, false, false, true);
4625 /* We may also need to adjust stack pointer for padding bytes
4626 because varargs may cause $sp not 8-byte aligned. */
4627 if (cfun->machine->va_args_area_padding_bytes)
4629 /* Generate sp adjustment instruction. */
4630 sp_adjust = cfun->machine->va_args_area_padding_bytes;
4632 nds32_emit_adjust_frame (stack_pointer_rtx,
4633 stack_pointer_rtx,
4634 -1 * sp_adjust);
4638 /* If the function is 'naked',
4639 we do not have to generate prologue code fragment. */
4640 if (cfun->machine->naked_p && !flag_pic)
4641 return;
4643 /* Get callee_first_regno and callee_last_regno. */
4644 Rb = cfun->machine->callee_saved_first_gpr_regno;
4645 Re = cfun->machine->callee_saved_last_gpr_regno;
4647 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4648 to be saved, we don't have to create multiple push instruction.
4649 Otherwise, a multiple push instruction is needed. */
4650 if (!(Rb == SP_REGNUM && Re == SP_REGNUM
4651 && cfun->machine->fp_size == 0
4652 && cfun->machine->gp_size == 0
4653 && cfun->machine->lp_size == 0))
4655 /* Create multiple push instruction rtx. */
4656 nds32_emit_stack_push_multiple (
4657 Rb, Re,
4658 cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size,
4659 false);
4662 /* Save eh data registers. */
4663 if (cfun->machine->use_eh_return_p)
4665 Rb = cfun->machine->eh_return_data_first_regno;
4666 Re = cfun->machine->eh_return_data_last_regno;
4668 /* No need to push $fp, $gp, or $lp.
4669 Also, this is not variadic arguments push. */
4670 nds32_emit_stack_push_multiple (Rb, Re, false, false, false, false);
4673 /* Check frame_pointer_needed to see
4674 if we shall emit fp adjustment instruction. */
4675 if (frame_pointer_needed)
4677 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
4678 + (4 * callee-saved-registers)
4679 + (4 * exception-handling-data-registers)
4680 Note: No need to adjust
4681 cfun->machine->callee_saved_area_gpr_padding_bytes,
4682 because, at this point, stack pointer is just
4683 at the position after push instruction. */
4684 fp_adjust = cfun->machine->fp_size
4685 + cfun->machine->gp_size
4686 + cfun->machine->lp_size
4687 + cfun->machine->callee_saved_gpr_regs_size
4688 + cfun->machine->eh_return_data_regs_size;
4690 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
4691 stack_pointer_rtx,
4692 fp_adjust);
4695 /* Save fpu registers. */
4696 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4698 /* When $sp moved to bottom of stack, we need to check whether
4699 the range of offset in the FPU instruction. */
4700 int fpr_offset = cfun->machine->local_size
4701 + cfun->machine->out_args_size
4702 + cfun->machine->callee_saved_fpr_regs_size;
4704 /* Check FPU instruction offset imm14s. */
4705 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset)))
4707 int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
4708 + cfun->machine->callee_saved_fpr_regs_size;
4710 /* Save fpu registers, need to allocate stack space
4711 for fpu callee registers. And now $sp position
4712 on callee saved fpr registers. */
4713 nds32_emit_adjust_frame (stack_pointer_rtx,
4714 stack_pointer_rtx,
4715 -1 * fpr_space);
4717 /* Emit fpu store instruction, using [$sp + offset] store
4718 fpu registers. */
4719 nds32_emit_push_fpr_callee_saved (0);
4721 /* Adjust $sp = $sp - local_size - out_args_size. */
4722 sp_adjust = cfun->machine->local_size
4723 + cfun->machine->out_args_size;
4725 /* Allocate stack space for local size and out args size. */
4726 nds32_emit_adjust_frame (stack_pointer_rtx,
4727 stack_pointer_rtx,
4728 -1 * sp_adjust);
4730 else
4732 /* Offset range in Is14, so $sp moved to bottom of stack. */
4734 /* Adjust $sp = $sp - local_size - out_args_size
4735 - callee_saved_area_gpr_padding_bytes
4736 - callee_saved_fpr_regs_size. */
4737 sp_adjust = cfun->machine->local_size
4738 + cfun->machine->out_args_size
4739 + cfun->machine->callee_saved_area_gpr_padding_bytes
4740 + cfun->machine->callee_saved_fpr_regs_size;
4742 nds32_emit_adjust_frame (stack_pointer_rtx,
4743 stack_pointer_rtx,
4744 -1 * sp_adjust);
4746 /* Emit fpu store instruction, using [$sp + offset] store
4747 fpu registers. */
4748 int fpr_position = cfun->machine->out_args_size
4749 + cfun->machine->local_size;
4750 nds32_emit_push_fpr_callee_saved (fpr_position);
4753 else
4755 /* Adjust $sp = $sp - local_size - out_args_size
4756 - callee_saved_area_gpr_padding_bytes. */
4757 sp_adjust = cfun->machine->local_size
4758 + cfun->machine->out_args_size
4759 + cfun->machine->callee_saved_area_gpr_padding_bytes;
4761 /* sp_adjust value may be out of range of the addi instruction,
4762 create alternative add behavior with TA_REGNUM if necessary,
4763 using NEGATIVE value to tell that we are decreasing address. */
4764 nds32_emit_adjust_frame (stack_pointer_rtx,
4765 stack_pointer_rtx,
4766 -1 * sp_adjust);
4769 /* Emit gp setup instructions for -fpic. */
4770 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
4771 nds32_emit_load_gp ();
4773 /* If user applies -mno-sched-prolog-epilog option,
4774 we need to prevent instructions of function body from being
4775 scheduled with stack adjustment in prologue. */
4776 if (!flag_sched_prolog_epilog)
4777 emit_insn (gen_blockage ());
4780 /* Function for normal multiple pop epilogue. */
4781 void
4782 nds32_expand_epilogue (bool sibcall_p)
4784 int sp_adjust;
4785 unsigned Rb, Re;
4787 /* Compute and setup stack frame size.
4788 The result will be in cfun->machine. */
4789 nds32_compute_stack_frame ();
4791 /* If user applies -mno-sched-prolog-epilog option,
4792 we need to prevent instructions of function body from being
4793 scheduled with stack adjustment in epilogue. */
4794 if (!flag_sched_prolog_epilog)
4795 emit_insn (gen_blockage ());
4797 /* If the function is 'naked', we do not have to generate
4798 epilogue code fragment BUT 'ret' instruction.
4799 However, if this function is also a variadic function,
4800 we need to create adjust stack pointer before 'ret' instruction. */
4801 if (cfun->machine->naked_p)
4803 /* If this is a variadic function, we do not have to restore argument
4804 registers but need to adjust stack pointer back to previous stack
4805 frame location before return. */
4806 if (cfun->machine->va_args_size != 0)
4808 /* Generate sp adjustment instruction.
4809 We need to consider padding bytes here. */
4810 sp_adjust = cfun->machine->va_args_size
4811 + cfun->machine->va_args_area_padding_bytes;
4813 nds32_emit_adjust_frame (stack_pointer_rtx,
4814 stack_pointer_rtx,
4815 sp_adjust);
4818 /* Generate return instruction by using 'return_internal' pattern.
4819 Make sure this instruction is after gen_blockage(). */
4820 if (!sibcall_p)
4822 /* We need to further check attributes to determine whether
4823 there should be return instruction at epilogue.
4824 If the attribute naked exists but -mno-ret-in-naked-func
4825 is issued, there is NO need to generate return instruction. */
4826 if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
4827 return;
4829 emit_jump_insn (gen_return_internal ());
4831 return;
4834 if (frame_pointer_needed)
4836 /* Restore fpu registers. */
4837 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4839 int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes;
4841 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4842 - (4 * callee-saved-registers)
4843 - (4 * exception-handling-data-registers)
4844 - (4 * callee-saved-gpr-registers padding byte)
4845 - (4 * callee-saved-fpr-registers)
4846 Note: we want to adjust stack pointer
4847 to the position for callee-saved fpr register,
4848 And restore fpu register use .bi instruction to adjust $sp
4849 from callee-saved fpr register to pop instruction. */
4850 sp_adjust = cfun->machine->fp_size
4851 + cfun->machine->gp_size
4852 + cfun->machine->lp_size
4853 + cfun->machine->callee_saved_gpr_regs_size
4854 + cfun->machine->eh_return_data_regs_size
4855 + cfun->machine->callee_saved_area_gpr_padding_bytes
4856 + cfun->machine->callee_saved_fpr_regs_size;
4858 nds32_emit_adjust_frame (stack_pointer_rtx,
4859 hard_frame_pointer_rtx,
4860 -1 * sp_adjust);
4862 /* Emit fpu load instruction, using .bi instruction
4863 load fpu registers. */
4864 nds32_emit_pop_fpr_callee_saved (gpr_padding);
4866 else
4868 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4869 - (4 * callee-saved-registers)
4870 - (4 * exception-handling-data-registers)
4871 Note: No need to adjust
4872 cfun->machine->callee_saved_area_gpr_padding_bytes,
4873 because we want to adjust stack pointer
4874 to the position for pop instruction. */
4875 sp_adjust = cfun->machine->fp_size
4876 + cfun->machine->gp_size
4877 + cfun->machine->lp_size
4878 + cfun->machine->callee_saved_gpr_regs_size
4879 + cfun->machine->eh_return_data_regs_size;
4881 nds32_emit_adjust_frame (stack_pointer_rtx,
4882 hard_frame_pointer_rtx,
4883 -1 * sp_adjust);
4886 else
4888 /* Restore fpu registers. */
4889 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4891 int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes;
4893 /* Adjust $sp = $sp + local_size + out_args_size. */
4894 sp_adjust = cfun->machine->local_size
4895 + cfun->machine->out_args_size;
4897 nds32_emit_adjust_frame (stack_pointer_rtx,
4898 stack_pointer_rtx,
4899 sp_adjust);
4901 /* Emit fpu load instruction, using .bi instruction
4902 load fpu registers, and adjust $sp from callee-saved fpr register
4903 to callee-saved gpr register. */
4904 nds32_emit_pop_fpr_callee_saved (gpr_padding);
4906 else
4908 /* If frame pointer is NOT needed,
4909 we cannot calculate the sp adjustment from frame pointer.
4910 Instead, we calculate the adjustment by local_size,
4911 out_args_size, and callee_saved_area_gpr_padding_bytes.
4912 Notice that such sp adjustment value may be out of range,
4913 so we have to deal with it as well. */
4915 /* Adjust $sp = $sp + local_size + out_args_size
4916 + callee_saved_area_gpr_padding_bytes. */
4917 sp_adjust = cfun->machine->local_size
4918 + cfun->machine->out_args_size
4919 + cfun->machine->callee_saved_area_gpr_padding_bytes;
4921 nds32_emit_adjust_frame (stack_pointer_rtx,
4922 stack_pointer_rtx,
4923 sp_adjust);
4927 /* Restore eh data registers. */
4928 if (cfun->machine->use_eh_return_p)
4930 Rb = cfun->machine->eh_return_data_first_regno;
4931 Re = cfun->machine->eh_return_data_last_regno;
4933 /* No need to pop $fp, $gp, or $lp. */
4934 nds32_emit_stack_pop_multiple (Rb, Re, false, false, false);
4937 /* Get callee_first_regno and callee_last_regno. */
4938 Rb = cfun->machine->callee_saved_first_gpr_regno;
4939 Re = cfun->machine->callee_saved_last_gpr_regno;
4941 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4942 to be saved, we don't have to create multiple pop instruction.
4943 Otherwise, a multiple pop instruction is needed. */
4944 if (!(Rb == SP_REGNUM && Re == SP_REGNUM
4945 && cfun->machine->fp_size == 0
4946 && cfun->machine->gp_size == 0
4947 && cfun->machine->lp_size == 0))
4949 /* Create multiple pop instruction rtx. */
4950 nds32_emit_stack_pop_multiple (
4951 Rb, Re,
4952 cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size);
4955 /* If this is a variadic function, we do not have to restore argument
4956 registers but need to adjust stack pointer back to previous stack
4957 frame location before return. */
4958 if (cfun->machine->va_args_size != 0)
4960 /* Generate sp adjustment instruction.
4961 We need to consider padding bytes here. */
4962 sp_adjust = cfun->machine->va_args_size
4963 + cfun->machine->va_args_area_padding_bytes;
4965 nds32_emit_adjust_frame (stack_pointer_rtx,
4966 stack_pointer_rtx,
4967 sp_adjust);
4970 /* If this function uses __builtin_eh_return, make stack adjustment
4971 for exception handler. */
4972 if (cfun->machine->use_eh_return_p)
4974 /* We need to unwind the stack by the offset computed by
4975 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4976 based on SP. Ideally we would update the SP and define the
4977 CFA along the lines of:
4979 SP = SP + EH_RETURN_STACKADJ_RTX
4980 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4982 However the dwarf emitter only understands a constant
4983 register offset.
4985 The solution chosen here is to use the otherwise $ta ($r15)
4986 as a temporary register to hold the current SP value. The
4987 CFA is described using $ta then SP is modified. */
4989 rtx ta_reg;
4990 rtx insn;
4992 ta_reg = gen_rtx_REG (SImode, TA_REGNUM);
4994 insn = emit_move_insn (ta_reg, stack_pointer_rtx);
4995 add_reg_note (insn, REG_CFA_DEF_CFA, ta_reg);
4996 RTX_FRAME_RELATED_P (insn) = 1;
4998 emit_insn (gen_addsi3 (stack_pointer_rtx,
4999 stack_pointer_rtx,
5000 EH_RETURN_STACKADJ_RTX));
5002 /* Ensure the assignment to $ta does not get optimized away. */
5003 emit_use (ta_reg);
5006 /* Generate return instruction. */
5007 if (!sibcall_p)
5008 emit_jump_insn (gen_return_internal ());
5011 /* Function for v3push prologue. */
5012 void
5013 nds32_expand_prologue_v3push (void)
5015 int fp_adjust;
5016 int sp_adjust;
5017 int fpr_space = 0;
5018 unsigned Rb, Re;
5020 /* Compute and setup stack frame size.
5021 The result will be in cfun->machine. */
5022 nds32_compute_stack_frame ();
5024 if (cfun->machine->callee_saved_gpr_regs_size > 0)
5025 df_set_regs_ever_live (FP_REGNUM, 1);
5027 /* Check frame_pointer_needed again to prevent fp is need after reload. */
5028 if (frame_pointer_needed)
5029 cfun->machine->fp_as_gp_p = false;
5031 /* If the function is 'naked',
5032 we do not have to generate prologue code fragment. */
5033 if (cfun->machine->naked_p && !flag_pic)
5034 return;
5036 /* Get callee_first_regno and callee_last_regno. */
5037 Rb = cfun->machine->callee_saved_first_gpr_regno;
5038 Re = cfun->machine->callee_saved_last_gpr_regno;
5040 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
5041 where imm8u has to be 8-byte alignment. */
5042 sp_adjust = cfun->machine->local_size
5043 + cfun->machine->out_args_size
5044 + cfun->machine->callee_saved_area_gpr_padding_bytes
5045 + cfun->machine->callee_saved_fpr_regs_size;
5047 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
5048 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
5050 /* We can use 'push25 Re,imm8u'. */
5052 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
5053 the pattern 'stack_v3push' is implemented in nds32.md. */
5054 nds32_emit_stack_v3push (Rb, Re, sp_adjust);
5056 /* Save fpu registers. */
5057 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5059 /* Calculate fpr position. */
5060 int fpr_position = cfun->machine->local_size
5061 + cfun->machine->out_args_size;
5062 /* Emit fpu store instruction, using [$sp + offset] store
5063 fpu registers. */
5064 nds32_emit_push_fpr_callee_saved (fpr_position);
5067 /* Check frame_pointer_needed to see
5068 if we shall emit fp adjustment instruction. */
5069 if (frame_pointer_needed)
5071 /* adjust $fp = $sp + 4 ($fp size)
5072 + 4 ($gp size)
5073 + 4 ($lp size)
5074 + (4 * n) (callee-saved registers)
5075 + sp_adjust ('push25 Re,imm8u')
5076 Note: Since we use 'push25 Re,imm8u',
5077 the position of stack pointer is further
5078 changed after push instruction.
5079 Hence, we need to take sp_adjust value
5080 into consideration. */
5081 fp_adjust = cfun->machine->fp_size
5082 + cfun->machine->gp_size
5083 + cfun->machine->lp_size
5084 + cfun->machine->callee_saved_gpr_regs_size
5085 + sp_adjust;
5087 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
5088 stack_pointer_rtx,
5089 fp_adjust);
5092 else
5094 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5096 /* Calculate fpr space. */
5097 fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
5098 + cfun->machine->callee_saved_fpr_regs_size;
5100 /* We have to use 'push25 Re, fpr_space', to pre-allocate
5101 callee saved fpr registers space. */
5102 nds32_emit_stack_v3push (Rb, Re, fpr_space);
5103 nds32_emit_push_fpr_callee_saved (0);
5105 else
5107 /* We have to use 'push25 Re,0' and
5108 expand one more instruction to adjust $sp later. */
5110 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
5111 the pattern 'stack_v3push' is implemented in nds32.md. */
5112 nds32_emit_stack_v3push (Rb, Re, 0);
5115 /* Check frame_pointer_needed to see
5116 if we shall emit fp adjustment instruction. */
5117 if (frame_pointer_needed)
5119 /* adjust $fp = $sp + 4 ($fp size)
5120 + 4 ($gp size)
5121 + 4 ($lp size)
5122 + (4 * n) (callee-saved registers)
5123 Note: Since we use 'push25 Re,0',
5124 the stack pointer is just at the position
5125 after push instruction.
5126 No need to take sp_adjust into consideration. */
5127 fp_adjust = cfun->machine->fp_size
5128 + cfun->machine->gp_size
5129 + cfun->machine->lp_size
5130 + cfun->machine->callee_saved_gpr_regs_size;
5132 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5134 /* We use 'push25 Re, fpr_space', the $sp is
5135 on callee saved fpr position, so need to consider
5136 fpr space. */
5137 fp_adjust = fp_adjust + fpr_space;
5140 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
5141 stack_pointer_rtx,
5142 fp_adjust);
5145 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5147 /* We use 'push25 Re, fpr_space',
5148 the $sp is on callee saved fpr position,
5149 no need to consider fpr space. */
5150 sp_adjust = sp_adjust - fpr_space;
5153 /* Because we use 'push25 Re,0',
5154 we need to expand one more instruction to adjust $sp.
5155 using NEGATIVE value to tell that we are decreasing address. */
5156 nds32_emit_adjust_frame (stack_pointer_rtx,
5157 stack_pointer_rtx,
5158 -1 * sp_adjust);
5161 /* Emit gp setup instructions for -fpic. */
5162 if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
5163 nds32_emit_load_gp ();
5165 /* Prevent the instruction scheduler from
5166 moving instructions across the boundary. */
5167 emit_insn (gen_blockage ());
5170 /* Function for v3pop epilogue. */
5171 void
5172 nds32_expand_epilogue_v3pop (bool sibcall_p)
5174 int sp_adjust;
5175 unsigned Rb, Re;
5177 /* Compute and setup stack frame size.
5178 The result will be in cfun->machine. */
5179 nds32_compute_stack_frame ();
5181 /* Prevent the instruction scheduler from
5182 moving instructions across the boundary. */
5183 emit_insn (gen_blockage ());
5185 /* If the function is 'naked', we do not have to generate
5186 epilogue code fragment BUT 'ret' instruction. */
5187 if (cfun->machine->naked_p)
5189 /* Generate return instruction by using 'return_internal' pattern.
5190 Make sure this instruction is after gen_blockage().
5191 First we need to check this is a function without sibling call. */
5192 if (!sibcall_p)
5194 /* We need to further check attributes to determine whether
5195 there should be return instruction at epilogue.
5196 If the attribute naked exists but -mno-ret-in-naked-func
5197 is issued, there is NO need to generate return instruction. */
5198 if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
5199 return;
5201 emit_jump_insn (gen_return_internal ());
5203 return;
5206 /* Get callee_first_regno and callee_last_regno. */
5207 Rb = cfun->machine->callee_saved_first_gpr_regno;
5208 Re = cfun->machine->callee_saved_last_gpr_regno;
5210 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
5211 where imm8u has to be 8-byte alignment. */
5212 sp_adjust = cfun->machine->local_size
5213 + cfun->machine->out_args_size
5214 + cfun->machine->callee_saved_area_gpr_padding_bytes
5215 + cfun->machine->callee_saved_fpr_regs_size;
5217 /* We have to consider alloca issue as well.
5218 If the function does call alloca(), the stack pointer is not fixed.
5219 In that case, we cannot use 'pop25 Re,imm8u' directly.
5220 We have to caculate stack pointer from frame pointer
5221 and then use 'pop25 Re,0'.
5222 Of course, the frame_pointer_needed should be nonzero
5223 if the function calls alloca(). */
5224 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
5225 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
5226 && !cfun->calls_alloca)
5228 /* Restore fpu registers. */
5229 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5231 int fpr_position = cfun->machine->local_size
5232 + cfun->machine->out_args_size;
5233 /* Emit fpu load instruction, using [$sp + offset] restore
5234 fpu registers. */
5235 nds32_emit_v3pop_fpr_callee_saved (fpr_position);
5238 /* We can use 'pop25 Re,imm8u'. */
5240 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
5241 the pattern 'stack_v3pop' is implementad in nds32.md. */
5242 nds32_emit_stack_v3pop (Rb, Re, sp_adjust);
5244 else
5246 /* We have to use 'pop25 Re,0', and prior to it,
5247 we must expand one more instruction to adjust $sp. */
5249 if (frame_pointer_needed)
5251 /* adjust $sp = $fp - 4 ($fp size)
5252 - 4 ($gp size)
5253 - 4 ($lp size)
5254 - (4 * n) (callee-saved registers)
5255 Note: No need to adjust
5256 cfun->machine->callee_saved_area_gpr_padding_bytes,
5257 because we want to adjust stack pointer
5258 to the position for pop instruction. */
5259 sp_adjust = cfun->machine->fp_size
5260 + cfun->machine->gp_size
5261 + cfun->machine->lp_size
5262 + cfun->machine->callee_saved_gpr_regs_size;
5264 /* Restore fpu registers. */
5265 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5267 /* Set $sp to callee saved fpr position, we need to restore
5268 fpr registers. */
5269 sp_adjust = sp_adjust
5270 + cfun->machine->callee_saved_area_gpr_padding_bytes
5271 + cfun->machine->callee_saved_fpr_regs_size;
5273 nds32_emit_adjust_frame (stack_pointer_rtx,
5274 hard_frame_pointer_rtx,
5275 -1 * sp_adjust);
5277 /* Emit fpu load instruction, using [$sp + offset] restore
5278 fpu registers. */
5279 nds32_emit_v3pop_fpr_callee_saved (0);
5281 else
5283 nds32_emit_adjust_frame (stack_pointer_rtx,
5284 hard_frame_pointer_rtx,
5285 -1 * sp_adjust);
5288 else
5290 /* If frame pointer is NOT needed,
5291 we cannot calculate the sp adjustment from frame pointer.
5292 Instead, we calculate the adjustment by local_size,
5293 out_args_size, and callee_saved_area_padding_bytes.
5294 Notice that such sp adjustment value may be out of range,
5295 so we have to deal with it as well. */
5297 /* Adjust $sp = $sp + local_size + out_args_size
5298 + callee_saved_area_gpr_padding_bytes
5299 + callee_saved_fpr_regs_size. */
5300 sp_adjust = cfun->machine->local_size
5301 + cfun->machine->out_args_size
5302 + cfun->machine->callee_saved_area_gpr_padding_bytes
5303 + cfun->machine->callee_saved_fpr_regs_size;
5305 /* Restore fpu registers. */
5306 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5308 /* Set $sp to callee saved fpr position, we need to restore
5309 fpr registers. */
5310 sp_adjust = sp_adjust
5311 - cfun->machine->callee_saved_area_gpr_padding_bytes
5312 - cfun->machine->callee_saved_fpr_regs_size;
5314 nds32_emit_adjust_frame (stack_pointer_rtx,
5315 stack_pointer_rtx,
5316 sp_adjust);
5318 /* Emit fpu load instruction, using [$sp + offset] restore
5319 fpu registers. */
5320 nds32_emit_v3pop_fpr_callee_saved (0);
5322 else
5324 /* sp_adjust value may be out of range of the addi instruction,
5325 create alternative add behavior with TA_REGNUM if necessary,
5326 using POSITIVE value to tell that we are increasing
5327 address. */
5328 nds32_emit_adjust_frame (stack_pointer_rtx,
5329 stack_pointer_rtx,
5330 sp_adjust);
5334 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
5336 /* We have fpr need to restore, so $sp is set on callee saved fpr
5337 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
5338 int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
5339 + cfun->machine->callee_saved_fpr_regs_size;
5340 nds32_emit_stack_v3pop (Rb, Re, fpr_space);
5342 else
5344 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
5345 the pattern 'stack_v3pop' is implementad in nds32.md. */
5346 nds32_emit_stack_v3pop (Rb, Re, 0);
5349 /* Generate return instruction. */
5350 emit_jump_insn (gen_pop25return ());
5353 /* Return nonzero if this function is known to have a null epilogue.
5354 This allows the optimizer to omit jumps to jumps if no stack
5355 was created. */
5357 nds32_can_use_return_insn (void)
5359 int sp_adjust;
5361 /* Prior to reloading, we can't tell how many registers must be saved.
5362 Thus we cannot determine whether this function has null epilogue. */
5363 if (!reload_completed)
5364 return 0;
5366 /* If attribute 'naked' appears but -mno-ret-in-naked-func is used,
5367 we cannot use return instruction. */
5368 if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func)
5369 return 0;
5371 sp_adjust = cfun->machine->local_size
5372 + cfun->machine->out_args_size
5373 + cfun->machine->callee_saved_area_gpr_padding_bytes
5374 + cfun->machine->callee_saved_fpr_regs_size;
5375 if (!cfun->machine->fp_as_gp_p
5376 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
5377 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
5378 && !cfun->calls_alloca
5379 && NDS32_V3PUSH_AVAILABLE_P
5380 && !(TARGET_HARD_FLOAT
5381 && (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)))
5382 return 1;
5384 /* If no stack was created, two conditions must be satisfied:
5385 1. This is a naked function.
5386 So there is no callee-saved, local size, or outgoing size.
5387 2. This is NOT a variadic function.
5388 So there is no pushing arguement registers into the stack. */
5389 return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0));
5392 scalar_int_mode
5393 nds32_case_vector_shorten_mode (int min_offset, int max_offset,
5394 rtx body ATTRIBUTE_UNUSED)
5396 if (min_offset < 0 || max_offset >= 0x2000)
5397 return SImode;
5398 else
5400 /* The jump table maybe need to 2 byte alignment,
5401 so reserved 1 byte for check max_offset. */
5402 if (max_offset >= 0xff)
5403 return HImode;
5404 else
5405 return QImode;
5409 /* ------------------------------------------------------------------------ */
5411 /* Return alignment for the label. */
5413 nds32_target_alignment (rtx_insn *label)
5415 rtx_insn *insn;
5417 if (!NDS32_ALIGN_P ())
5418 return 0;
5420 insn = next_active_insn (label);
5422 /* Always align to 4 byte when first instruction after label is jump
5423 instruction since length for that might changed, so let's always align
5424 it for make sure we don't lose any perfomance here. */
5425 if (insn == 0
5426 || (get_attr_length (insn) == 2
5427 && !JUMP_P (insn) && !CALL_P (insn)))
5428 return 0;
5429 else
5430 return 2;
5433 /* Return alignment for data. */
5434 unsigned int
5435 nds32_data_alignment (tree data,
5436 unsigned int basic_align)
5438 if ((basic_align < BITS_PER_WORD)
5439 && (TREE_CODE (data) == ARRAY_TYPE
5440 || TREE_CODE (data) == UNION_TYPE
5441 || TREE_CODE (data) == RECORD_TYPE))
5442 return BITS_PER_WORD;
5443 else
5444 return basic_align;
5447 /* Return alignment for constant value. */
5448 static HOST_WIDE_INT
5449 nds32_constant_alignment (const_tree constant,
5450 HOST_WIDE_INT basic_align)
5452 /* Make string literal and constant for constructor to word align. */
5453 if (((TREE_CODE (constant) == STRING_CST
5454 || TREE_CODE (constant) == CONSTRUCTOR
5455 || TREE_CODE (constant) == UNION_TYPE
5456 || TREE_CODE (constant) == RECORD_TYPE
5457 || TREE_CODE (constant) == ARRAY_TYPE)
5458 && basic_align < BITS_PER_WORD))
5459 return BITS_PER_WORD;
5460 else
5461 return basic_align;
5464 /* Return alignment for local variable. */
5465 unsigned int
5466 nds32_local_alignment (tree local ATTRIBUTE_UNUSED,
5467 unsigned int basic_align)
5469 bool at_least_align_to_word = false;
5470 /* Make local array, struct and union at least align to word for make
5471 sure it can unroll memcpy when initialize by constant. */
5472 switch (TREE_CODE (local))
5474 case ARRAY_TYPE:
5475 case RECORD_TYPE:
5476 case UNION_TYPE:
5477 at_least_align_to_word = true;
5478 break;
5479 default:
5480 at_least_align_to_word = false;
5481 break;
5483 if (at_least_align_to_word
5484 && (basic_align < BITS_PER_WORD))
5485 return BITS_PER_WORD;
5486 else
5487 return basic_align;
5490 bool
5491 nds32_split_double_word_load_store_p(rtx *operands, bool load_p)
5493 rtx mem = load_p ? operands[1] : operands[0];
5494 /* Do split at split2 if -O0 or schedule 2 not enable. */
5495 if (optimize == 0 || !flag_schedule_insns_after_reload)
5496 return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem);
5498 /* Split double word load store after copy propgation. */
5499 if (current_pass == NULL)
5500 return false;
5502 const char *pass_name = current_pass->name;
5503 if (pass_name && ((strcmp (pass_name, "split3") == 0)
5504 || (strcmp (pass_name, "split5") == 0)))
5505 return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem);
5507 return false;
5510 static bool
5511 nds32_use_blocks_for_constant_p (machine_mode mode,
5512 const_rtx x ATTRIBUTE_UNUSED)
5514 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
5515 && (mode == DFmode || mode == SFmode))
5516 return true;
5517 else
5518 return false;
5521 /* ------------------------------------------------------------------------ */
5523 /* PART 5: Initialize target hook structure and definitions. */
5525 /* Controlling the Compilation Driver. */
5528 /* Run-time Target Specification. */
5531 /* Defining Data Structures for Per-function Information. */
5534 /* Storage Layout. */
5536 #undef TARGET_PROMOTE_FUNCTION_MODE
5537 #define TARGET_PROMOTE_FUNCTION_MODE \
5538 default_promote_function_mode_always_promote
5540 #undef TARGET_EXPAND_TO_RTL_HOOK
5541 #define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
5543 #undef TARGET_CONSTANT_ALIGNMENT
5544 #define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment
5547 /* Layout of Source Language Data Types. */
5550 /* Register Usage. */
5552 /* -- Basic Characteristics of Registers. */
5554 #undef TARGET_CONDITIONAL_REGISTER_USAGE
5555 #define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
5557 /* -- Order of Allocation of Registers. */
5559 /* -- How Values Fit in Registers. */
5561 #undef TARGET_HARD_REGNO_NREGS
5562 #define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
5564 #undef TARGET_HARD_REGNO_MODE_OK
5565 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
5567 #undef TARGET_MODES_TIEABLE_P
5568 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
5570 /* -- Handling Leaf Functions. */
5572 /* -- Registers That Form a Stack. */
5575 /* Register Classes. */
5577 #undef TARGET_CLASS_MAX_NREGS
5578 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
5580 #undef TARGET_REGISTER_PRIORITY
5581 #define TARGET_REGISTER_PRIORITY nds32_register_priority
5583 #undef TARGET_CAN_CHANGE_MODE_CLASS
5584 #define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
5587 /* Obsolete Macros for Defining Constraints. */
5590 /* Stack Layout and Calling Conventions. */
5592 /* -- Basic Stack Layout. */
5594 /* -- Exception Handling Support. */
5596 /* -- Specifying How Stack Checking is Done. */
5598 /* -- Registers That Address the Stack Frame. */
5600 /* -- Eliminating Frame Pointer and Arg Pointer. */
5602 #undef TARGET_CAN_ELIMINATE
5603 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
5605 /* -- Passing Function Arguments on the Stack. */
5607 /* -- Passing Arguments in Registers. */
5609 #undef TARGET_FUNCTION_ARG
5610 #define TARGET_FUNCTION_ARG nds32_function_arg
5612 #undef TARGET_MUST_PASS_IN_STACK
5613 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
5615 #undef TARGET_ARG_PARTIAL_BYTES
5616 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
5618 #undef TARGET_FUNCTION_ARG_ADVANCE
5619 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5621 #undef TARGET_FUNCTION_ARG_BOUNDARY
5622 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5624 #undef TARGET_VECTOR_MODE_SUPPORTED_P
5625 #define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p
5627 /* -- How Scalar Function Values Are Returned. */
5629 #undef TARGET_FUNCTION_VALUE
5630 #define TARGET_FUNCTION_VALUE nds32_function_value
5632 #undef TARGET_LIBCALL_VALUE
5633 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5635 #undef TARGET_FUNCTION_VALUE_REGNO_P
5636 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5638 /* -- How Large Values Are Returned. */
5640 #undef TARGET_RETURN_IN_MEMORY
5641 #define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
5643 /* -- Caller-Saves Register Allocation. */
5645 /* -- Function Entry and Exit. */
5647 #undef TARGET_ASM_FUNCTION_PROLOGUE
5648 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5650 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5651 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5653 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5654 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5656 #undef TARGET_ASM_FUNCTION_EPILOGUE
5657 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5659 #undef TARGET_ASM_OUTPUT_MI_THUNK
5660 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5662 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5663 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5665 /* -- Generating Code for Profiling. */
5667 /* -- Permitting tail calls. */
5669 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5670 #define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
5672 #undef TARGET_WARN_FUNC_RETURN
5673 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5675 /* Stack smashing protection. */
5678 /* Implementing the Varargs Macros. */
5680 #undef TARGET_SETUP_INCOMING_VARARGS
5681 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5683 #undef TARGET_STRICT_ARGUMENT_NAMING
5684 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5687 /* Trampolines for Nested Functions. */
5689 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5690 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5692 #undef TARGET_TRAMPOLINE_INIT
5693 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5696 /* Implicit Calls to Library Routines. */
5699 /* Addressing Modes. */
5701 #undef TARGET_LEGITIMATE_ADDRESS_P
5702 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5704 #undef TARGET_LEGITIMIZE_ADDRESS
5705 #define TARGET_LEGITIMIZE_ADDRESS nds32_legitimize_address
5707 #undef TARGET_LEGITIMATE_CONSTANT_P
5708 #define TARGET_LEGITIMATE_CONSTANT_P nds32_legitimate_constant_p
5710 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
5711 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode
5713 #undef TARGET_CANNOT_FORCE_CONST_MEM
5714 #define TARGET_CANNOT_FORCE_CONST_MEM nds32_cannot_force_const_mem
5716 #undef TARGET_DELEGITIMIZE_ADDRESS
5717 #define TARGET_DELEGITIMIZE_ADDRESS nds32_delegitimize_address
5720 /* Anchored Addresses. */
5723 /* Condition Code Status. */
5725 /* -- Representation of condition codes using (cc0). */
5727 /* -- Representation of condition codes using registers. */
5729 #undef TARGET_CANONICALIZE_COMPARISON
5730 #define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5732 /* -- Macros to control conditional execution. */
5735 /* Describing Relative Costs of Operations. */
5737 #undef TARGET_REGISTER_MOVE_COST
5738 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5740 #undef TARGET_MEMORY_MOVE_COST
5741 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5743 #undef TARGET_RTX_COSTS
5744 #define TARGET_RTX_COSTS nds32_rtx_costs
5746 #undef TARGET_ADDRESS_COST
5747 #define TARGET_ADDRESS_COST nds32_address_cost
5750 /* Adjusting the Instruction Scheduler. */
5753 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5755 #undef TARGET_ENCODE_SECTION_INFO
5756 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5759 /* Position Independent Code. */
5762 /* Defining the Output Assembler Language. */
5764 /* -- The Overall Framework of an Assembler File. */
5766 #undef TARGET_ASM_FILE_START
5767 #define TARGET_ASM_FILE_START nds32_asm_file_start
5768 #undef TARGET_ASM_FILE_END
5769 #define TARGET_ASM_FILE_END nds32_asm_file_end
5771 /* -- Output of Data. */
5773 #undef TARGET_ASM_ALIGNED_HI_OP
5774 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5776 #undef TARGET_ASM_ALIGNED_SI_OP
5777 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5779 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
5780 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nds32_asm_output_addr_const_extra
5782 /* -- Output of Uninitialized Variables. */
5784 /* -- Output and Generation of Labels. */
5786 #undef TARGET_ASM_GLOBALIZE_LABEL
5787 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5789 /* -- How Initialization Functions Are Handled. */
5791 /* -- Macros Controlling Initialization Routines. */
5793 /* -- Output of Assembler Instructions. */
5795 #undef TARGET_PRINT_OPERAND
5796 #define TARGET_PRINT_OPERAND nds32_print_operand
5797 #undef TARGET_PRINT_OPERAND_ADDRESS
5798 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5800 /* -- Output of Dispatch Tables. */
5802 /* -- Assembler Commands for Exception Regions. */
5804 #undef TARGET_DWARF_REGISTER_SPAN
5805 #define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5807 /* -- Assembler Commands for Alignment. */
5810 /* Controlling Debugging Information Format. */
5812 /* -- Macros Affecting All Debugging Formats. */
5814 /* -- Macros for DWARF Output. */
5816 /* -- Macros for VMS Debug Format. */
5819 /* Cross Compilation and Floating Point. */
5822 /* Mode Switching Instructions. */
5825 /* Defining target-specific uses of __attribute__. */
5827 #undef TARGET_ATTRIBUTE_TABLE
5828 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5830 #undef TARGET_MERGE_DECL_ATTRIBUTES
5831 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5833 #undef TARGET_INSERT_ATTRIBUTES
5834 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5836 #undef TARGET_OPTION_PRAGMA_PARSE
5837 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5839 #undef TARGET_OPTION_OVERRIDE
5840 #define TARGET_OPTION_OVERRIDE nds32_option_override
5843 /* Emulating TLS. */
5845 #undef TARGET_HAVE_TLS
5846 #define TARGET_HAVE_TLS TARGET_LINUX_ABI
5849 /* Defining coprocessor specifics for MIPS targets. */
5852 /* Parameters for Precompiled Header Validity Checking. */
5855 /* C++ ABI parameters. */
5858 /* Adding support for named address spaces. */
5861 /* Miscellaneous Parameters. */
5863 #undef TARGET_MD_ASM_ADJUST
5864 #define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5866 #undef TARGET_INIT_BUILTINS
5867 #define TARGET_INIT_BUILTINS nds32_init_builtins
5869 #undef TARGET_BUILTIN_DECL
5870 #define TARGET_BUILTIN_DECL nds32_builtin_decl
5872 #undef TARGET_EXPAND_BUILTIN
5873 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5875 #undef TARGET_INIT_LIBFUNCS
5876 #define TARGET_INIT_LIBFUNCS nds32_init_libfuncs
5878 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5879 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5881 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
5882 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
5885 /* ------------------------------------------------------------------------ */
5887 /* Initialize the GCC target structure. */
5889 struct gcc_target targetm = TARGET_INITIALIZER;
5891 /* ------------------------------------------------------------------------ */