]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/nds32/nds32.c
[NDS32] Move some target hooks to the bottom of nds32.c file.
[thirdparty/gcc.git] / gcc / config / nds32 / nds32.c
CommitLineData
9304f876 1/* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
85ec4feb 2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
9304f876
CJW
3 Contributed by Andes Technology Corporation.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
19ac960a 21/* ------------------------------------------------------------------------ */
9304f876 22
8fcc61f8
RS
23#define IN_TARGET_CODE 1
24
9304f876
CJW
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
c7131fb2 28#include "backend.h"
e11c4407 29#include "target.h"
c7131fb2 30#include "rtl.h"
e11c4407 31#include "tree.h"
c4d8d050 32#include "tree-pass.h"
314e6352
ML
33#include "stringpool.h"
34#include "attribs.h"
c7131fb2 35#include "df.h"
4d0cdd0c 36#include "memmodel.h"
e11c4407
AM
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"
d8a2d370
DN
43#include "stor-layout.h"
44#include "varasm.h"
45#include "calls.h"
9304f876 46#include "output.h"
36566b39 47#include "explow.h"
9304f876 48#include "expr.h"
9304f876 49#include "tm-constrs.h"
9b2b7279 50#include "builtins.h"
72b7e5e1 51#include "cpplib.h"
c4d8d050 52#include "context.h"
9304f876 53
994c5d85 54/* This file should be included last. */
d58627a0
RS
55#include "target-def.h"
56
9304f876
CJW
57/* ------------------------------------------------------------------------ */
58
59/* This file is divided into five parts:
60
61 PART 1: Auxiliary static variable definitions and
62 target hook static variable definitions.
63
64 PART 2: Auxiliary static function definitions.
65
66 PART 3: Implement target hook stuff definitions.
67
68 PART 4: Implemet extern function definitions,
69 the prototype is in nds32-protos.h.
70
71 PART 5: Initialize target hook structure and definitions. */
72
73/* ------------------------------------------------------------------------ */
74
75/* PART 1: Auxiliary static variable definitions and
76 target hook static variable definitions. */
77
9304f876
CJW
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. */
82static const char * const nds32_intrinsic_register_names[] =
83{
2095a9d5
MC
84 "$CPU_VER",
85 "$ICM_CFG",
86 "$DCM_CFG",
87 "$MMU_CFG",
88 "$MSC_CFG",
89 "$MSC_CFG2",
90 "$CORE_ID",
91 "$FUCOP_EXIST",
92
93 "$PSW",
94 "$IPSW",
95 "$P_IPSW",
96 "$IVB",
97 "$EVA",
98 "$P_EVA",
99 "$ITYPE",
100 "$P_ITYPE",
101
102 "$MERR",
103 "$IPC",
104 "$P_IPC",
105 "$OIPC",
106 "$P_P0",
107 "$P_P1",
108
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",
125
126 "$MMU_CTL",
127 "$L1_PPTB",
128 "$TLB_VPN",
129 "$TLB_DATA",
130 "$TLB_MISC",
131 "$VLPT_IDX",
132 "$ILMB",
133 "$DLMB",
134
135 "$CACHE_CTL",
136 "$HSMP_SADDR",
137 "$HSMP_EADDR",
138 "$SDZ_CTL",
139 "$N12MISC_CTL",
140 "$MISC_CTL",
141 "$ECC_MISC",
142
143 "$BPC0",
144 "$BPC1",
145 "$BPC2",
146 "$BPC3",
147 "$BPC4",
148 "$BPC5",
149 "$BPC6",
150 "$BPC7",
151
152 "$BPA0",
153 "$BPA1",
154 "$BPA2",
155 "$BPA3",
156 "$BPA4",
157 "$BPA5",
158 "$BPA6",
159 "$BPA7",
160
161 "$BPAM0",
162 "$BPAM1",
163 "$BPAM2",
164 "$BPAM3",
165 "$BPAM4",
166 "$BPAM5",
167 "$BPAM6",
168 "$BPAM7",
169
170 "$BPV0",
171 "$BPV1",
172 "$BPV2",
173 "$BPV3",
174 "$BPV4",
175 "$BPV5",
176 "$BPV6",
177 "$BPV7",
178
179 "$BPCID0",
180 "$BPCID1",
181 "$BPCID2",
182 "$BPCID3",
183 "$BPCID4",
184 "$BPCID5",
185 "$BPCID6",
186 "$BPCID7",
187
188 "$EDM_CFG",
189 "$EDMSW",
190 "$EDM_CTL",
191 "$EDM_DTR",
192 "$BPMTC",
193 "$DIMBR",
194
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",
209
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",
223
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"
9304f876
CJW
238};
239
f1a0afe2
MC
240/* Define instrinsic cctl names. */
241static const char * const nds32_cctl_names[] =
242{
243 "L1D_VA_FILLCK",
244 "L1D_VA_ULCK",
245 "L1I_VA_FILLCK",
246 "L1I_VA_ULCK",
247
248 "L1D_IX_WBINVAL",
249 "L1D_IX_INVAL",
250 "L1D_IX_WB",
251 "L1I_IX_INVAL",
252
253 "L1D_VA_INVAL",
254 "L1D_VA_WB",
255 "L1D_VA_WBINVAL",
256 "L1I_VA_INVAL",
257
258 "L1D_IX_RTAG",
259 "L1D_IX_RWD",
260 "L1I_IX_RTAG",
261 "L1I_IX_RWD",
262
263 "L1D_IX_WTAG",
264 "L1D_IX_WWD",
265 "L1I_IX_WTAG",
266 "L1I_IX_WWD"
267};
5e6ae0cc 268
57aaf0cc
MC
269static const char * const nds32_dpref_names[] =
270{
271 "SRD",
272 "MRD",
273 "SWR",
274 "MWR",
275 "PTE",
276 "CLWR"
277};
278
5e6ae0cc
CJW
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(). */
282static const int nds32_reg_alloc_order_for_speed[] =
283{
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
288};
289
9304f876
CJW
290/* Defining target-specific uses of __attribute__. */
291static const struct attribute_spec nds32_attribute_table[] =
292{
293 /* Syntax: { name, min_len, max_len, decl_required, type_required,
4849deb1
JJ
294 function_type_required, affects_type_identity, handler,
295 exclude } */
9304f876
CJW
296
297 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
4849deb1 298 { "interrupt", 1, 64, false, false, false, false, NULL, NULL },
9304f876 299 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
4849deb1 300 { "exception", 1, 8, false, false, false, false, NULL, NULL },
9304f876 301 /* Argument is user's interrupt numbers. The vector number is always 0. */
4849deb1 302 { "reset", 1, 1, false, false, false, false, NULL, NULL },
9304f876
CJW
303
304 /* The attributes describing isr nested type. */
4849deb1
JJ
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 },
9304f876
CJW
308
309 /* The attributes describing isr register save scheme. */
4849deb1
JJ
310 { "save_all", 0, 0, false, false, false, false, NULL, NULL },
311 { "partial_save", 0, 0, false, false, false, false, NULL, NULL },
9304f876
CJW
312
313 /* The attributes used by reset attribute. */
4849deb1
JJ
314 { "nmi", 1, 1, false, false, false, false, NULL, NULL },
315 { "warm", 1, 1, false, false, false, false, NULL, NULL },
9304f876
CJW
316
317 /* The attribute telling no prologue/epilogue. */
4849deb1 318 { "naked", 0, 0, false, false, false, false, NULL, NULL },
9304f876
CJW
319
320 /* The last attribute spec is set to be NULL. */
4849deb1 321 { NULL, 0, 0, false, false, false, false, NULL, NULL }
9304f876
CJW
322};
323
324
325/* ------------------------------------------------------------------------ */
326
327/* PART 2: Auxiliary static function definitions. */
328
329/* Function to save and restore machine-specific function data. */
330static struct machine_function *
331nds32_init_machine_status (void)
332{
333 struct machine_function *machine;
766090c2 334 machine = ggc_cleared_alloc<machine_function> ();
9304f876 335
ca3a4a55
CJW
336 /* Initially assume this function does not use __builtin_eh_return. */
337 machine->use_eh_return_p = 0;
338
9304f876
CJW
339 /* Initially assume this function needs prologue/epilogue. */
340 machine->naked_p = 0;
341
342 /* Initially assume this function does NOT use fp_as_gp optimization. */
343 machine->fp_as_gp_p = 0;
344
5f2a98c3
CJW
345 /* Initially this function is not under strictly aligned situation. */
346 machine->strict_aligned_p = 0;
347
9304f876
CJW
348 return machine;
349}
350
351/* Function to compute stack frame size and
352 store into cfun->machine structure. */
353static void
354nds32_compute_stack_frame (void)
355{
356 int r;
357 int block_size;
a6c7e777 358 bool v3pushpop_p;
9304f876
CJW
359
360 /* Because nds32_compute_stack_frame() will be called from different place,
361 everytime we enter this function, we have to assume this function
362 needs prologue/epilogue. */
363 cfun->machine->naked_p = 0;
364
ca3a4a55
CJW
365
366 /* If __builtin_eh_return is used, we better have frame pointer needed
367 so that we can easily locate the stack slot of return address. */
368 if (crtl->calls_eh_return)
369 {
370 frame_pointer_needed = 1;
371
372 /* We need to mark eh data registers that need to be saved
373 in the stack. */
374 cfun->machine->eh_return_data_first_regno = EH_RETURN_DATA_REGNO (0);
375 for (r = 0; EH_RETURN_DATA_REGNO (r) != INVALID_REGNUM; r++)
376 cfun->machine->eh_return_data_last_regno = r;
377
378 cfun->machine->eh_return_data_regs_size
379 = 4 * (cfun->machine->eh_return_data_last_regno
380 - cfun->machine->eh_return_data_first_regno
381 + 1);
382 cfun->machine->use_eh_return_p = 1;
383 }
384 else
385 {
386 /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we
387 do not need to handle __builtin_eh_return case in this function. */
388 cfun->machine->eh_return_data_first_regno = SP_REGNUM;
389 cfun->machine->eh_return_data_last_regno = SP_REGNUM;
390
391 cfun->machine->eh_return_data_regs_size = 0;
392 cfun->machine->use_eh_return_p = 0;
393 }
394
9304f876 395 /* Get variadic arguments size to prepare pretend arguments and
35da54a6
CJW
396 we will push them into stack at prologue by ourself. */
397 cfun->machine->va_args_size = crtl->args.pretend_args_size;
398 if (cfun->machine->va_args_size != 0)
399 {
400 cfun->machine->va_args_first_regno
8a498f99
CJW
401 = NDS32_GPR_ARG_FIRST_REGNUM
402 + NDS32_MAX_GPR_REGS_FOR_ARGS
403 - (crtl->args.pretend_args_size / UNITS_PER_WORD);
35da54a6 404 cfun->machine->va_args_last_regno
8a498f99 405 = NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS - 1;
35da54a6
CJW
406 }
407 else
408 {
409 cfun->machine->va_args_first_regno = SP_REGNUM;
410 cfun->machine->va_args_last_regno = SP_REGNUM;
411 }
412
413 /* Important: We need to make sure that varargs area is 8-byte alignment. */
414 block_size = cfun->machine->va_args_size;
415 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
416 {
417 cfun->machine->va_args_area_padding_bytes
418 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
419 }
9304f876
CJW
420
421 /* Get local variables, incoming variables, and temporary variables size.
422 Note that we need to make sure it is 8-byte alignment because
423 there may be no padding bytes if we are using LRA. */
424 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
425
426 /* Get outgoing arguments size. */
427 cfun->machine->out_args_size = crtl->outgoing_args_size;
428
429 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
430 Check whether $fp is ever live. */
431 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
432
433 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
434 Check whether we are using PIC code genration. */
435 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
436
437 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
438 Check whether $lp is ever live. */
439 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
440
441 /* Initially there is no padding bytes. */
c457f751 442 cfun->machine->callee_saved_area_gpr_padding_bytes = 0;
9304f876
CJW
443
444 /* Calculate the bytes of saving callee-saved registers on stack. */
c457f751
CJW
445 cfun->machine->callee_saved_gpr_regs_size = 0;
446 cfun->machine->callee_saved_first_gpr_regno = SP_REGNUM;
447 cfun->machine->callee_saved_last_gpr_regno = SP_REGNUM;
e2286268
MC
448 cfun->machine->callee_saved_fpr_regs_size = 0;
449 cfun->machine->callee_saved_first_fpr_regno = SP_REGNUM;
450 cfun->machine->callee_saved_last_fpr_regno = SP_REGNUM;
451
9304f876
CJW
452 /* Currently, there is no need to check $r28~$r31
453 because we will save them in another way. */
454 for (r = 0; r < 28; r++)
455 {
456 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
457 {
458 /* Mark the first required callee-saved register
459 (only need to set it once).
460 If first regno == SP_REGNUM, we can tell that
461 it is the first time to be here. */
c457f751
CJW
462 if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM)
463 cfun->machine->callee_saved_first_gpr_regno = r;
9304f876 464 /* Mark the last required callee-saved register. */
c457f751 465 cfun->machine->callee_saved_last_gpr_regno = r;
9304f876
CJW
466 }
467 }
468
e2286268
MC
469 /* Recording fpu callee-saved register. */
470 if (TARGET_HARD_FLOAT)
471 {
472 for (r = NDS32_FIRST_FPR_REGNUM; r < NDS32_LAST_FPR_REGNUM; r++)
473 {
474 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
475 {
476 /* Mark the first required callee-saved register. */
477 if (cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM)
478 {
479 /* Make first callee-saved number is even,
480 bacause we use doubleword access, and this way
481 promise 8-byte alignemt. */
482 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r))
483 cfun->machine->callee_saved_first_fpr_regno = r - 1;
484 else
485 cfun->machine->callee_saved_first_fpr_regno = r;
486 }
487 cfun->machine->callee_saved_last_fpr_regno = r;
488 }
489 }
490
491 /* Make last callee-saved register number is odd,
492 we hope callee-saved register is even. */
493 int last_fpr = cfun->machine->callee_saved_last_fpr_regno;
494 if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr))
495 cfun->machine->callee_saved_last_fpr_regno++;
496 }
497
9304f876
CJW
498 /* Check if this function can omit prologue/epilogue code fragment.
499 If there is 'naked' attribute in this function,
500 we can set 'naked_p' flag to indicate that
501 we do not have to generate prologue/epilogue.
502 Or, if all the following conditions succeed,
503 we can set this function 'naked_p' as well:
504 condition 1: first_regno == last_regno == SP_REGNUM,
8a498f99
CJW
505 which means we do not have to save
506 any callee-saved registers.
9304f876 507 condition 2: Both $lp and $fp are NOT live in this function,
8a498f99
CJW
508 which means we do not need to save them and there
509 is no outgoing size.
9304f876 510 condition 3: There is no local_size, which means
8a498f99 511 we do not need to adjust $sp. */
9304f876 512 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
c457f751
CJW
513 || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM
514 && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM
e2286268
MC
515 && cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM
516 && cfun->machine->callee_saved_last_fpr_regno == SP_REGNUM
9304f876
CJW
517 && !df_regs_ever_live_p (FP_REGNUM)
518 && !df_regs_ever_live_p (LP_REGNUM)
519 && cfun->machine->local_size == 0))
520 {
2da1e7c0 521 /* Set this function 'naked_p' and other functions can check this flag.
8a498f99
CJW
522 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
523 callee-saved, local size, and outgoing size.
524 The varargs space and ret instruction may still present in
525 the prologue/epilogue expanding. */
9304f876
CJW
526 cfun->machine->naked_p = 1;
527
528 /* No need to save $fp, $gp, and $lp.
8a498f99
CJW
529 We should set these value to be zero
530 so that nds32_initial_elimination_offset() can work properly. */
9304f876
CJW
531 cfun->machine->fp_size = 0;
532 cfun->machine->gp_size = 0;
533 cfun->machine->lp_size = 0;
534
535 /* If stack usage computation is required,
8a498f99 536 we need to provide the static stack size. */
9304f876
CJW
537 if (flag_stack_usage_info)
538 current_function_static_stack_size = 0;
539
540 /* No need to do following adjustment, return immediately. */
541 return;
542 }
543
a6c7e777
MC
544 v3pushpop_p = NDS32_V3PUSH_AVAILABLE_P;
545
9304f876
CJW
546 /* Adjustment for v3push instructions:
547 If we are using v3push (push25/pop25) instructions,
548 we need to make sure Rb is $r6 and Re is
549 located on $r6, $r8, $r10, or $r14.
550 Some results above will be discarded and recomputed.
2da1e7c0
CJW
551 Note that it is only available under V3/V3M ISA and we
552 DO NOT setup following stuff for isr or variadic function. */
a6c7e777 553 if (v3pushpop_p)
9304f876
CJW
554 {
555 /* Recompute:
8a498f99
CJW
556 cfun->machine->fp_size
557 cfun->machine->gp_size
558 cfun->machine->lp_size
559 cfun->machine->callee_saved_first_gpr_regno
560 cfun->machine->callee_saved_last_gpr_regno */
9304f876
CJW
561
562 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
563 cfun->machine->fp_size = 4;
564 cfun->machine->gp_size = 4;
565 cfun->machine->lp_size = 4;
566
567 /* Remember to set Rb = $r6. */
c457f751 568 cfun->machine->callee_saved_first_gpr_regno = 6;
9304f876 569
c457f751 570 if (cfun->machine->callee_saved_last_gpr_regno <= 6)
9304f876
CJW
571 {
572 /* Re = $r6 */
c457f751 573 cfun->machine->callee_saved_last_gpr_regno = 6;
9304f876 574 }
c457f751 575 else if (cfun->machine->callee_saved_last_gpr_regno <= 8)
9304f876
CJW
576 {
577 /* Re = $r8 */
c457f751 578 cfun->machine->callee_saved_last_gpr_regno = 8;
9304f876 579 }
c457f751 580 else if (cfun->machine->callee_saved_last_gpr_regno <= 10)
9304f876
CJW
581 {
582 /* Re = $r10 */
c457f751 583 cfun->machine->callee_saved_last_gpr_regno = 10;
9304f876 584 }
c457f751 585 else if (cfun->machine->callee_saved_last_gpr_regno <= 14)
9304f876
CJW
586 {
587 /* Re = $r14 */
c457f751 588 cfun->machine->callee_saved_last_gpr_regno = 14;
9304f876 589 }
c457f751 590 else if (cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM)
9304f876
CJW
591 {
592 /* If last_regno is SP_REGNUM, which means
593 it is never changed, so set it to Re = $r6. */
c457f751 594 cfun->machine->callee_saved_last_gpr_regno = 6;
9304f876
CJW
595 }
596 else
597 {
598 /* The program flow should not go here. */
599 gcc_unreachable ();
600 }
601 }
602
a6c7e777
MC
603 int sp_adjust = cfun->machine->local_size
604 + cfun->machine->out_args_size
e2286268
MC
605 + cfun->machine->callee_saved_area_gpr_padding_bytes
606 + cfun->machine->callee_saved_fpr_regs_size;
a6c7e777
MC
607
608 if (!v3pushpop_p
609 && sp_adjust == 0
610 && !frame_pointer_needed)
611 {
612 block_size = cfun->machine->fp_size
613 + cfun->machine->gp_size
614 + cfun->machine->lp_size
615 + (4 * (cfun->machine->callee_saved_last_gpr_regno
616 - cfun->machine->callee_saved_first_gpr_regno
617 + 1));
618
619 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
620 {
621 /* $r14 is last callee save register. */
622 if (cfun->machine->callee_saved_last_gpr_regno
623 < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM)
624 {
625 cfun->machine->callee_saved_last_gpr_regno++;
626 }
627 else if (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM)
628 {
629 cfun->machine->callee_saved_first_gpr_regno
630 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM;
631 cfun->machine->callee_saved_last_gpr_regno
632 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM;
633 }
634 }
635 }
636
8a498f99
CJW
637 /* We have correctly set callee_saved_first_gpr_regno
638 and callee_saved_last_gpr_regno.
639 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
640 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
641 we can update callee_saved_gpr_regs_size with new size. */
c457f751 642 if (cfun->machine->callee_saved_last_gpr_regno != SP_REGNUM)
9304f876
CJW
643 {
644 /* Compute pushed size of callee-saved registers. */
c457f751
CJW
645 cfun->machine->callee_saved_gpr_regs_size
646 = 4 * (cfun->machine->callee_saved_last_gpr_regno
647 - cfun->machine->callee_saved_first_gpr_regno
9304f876
CJW
648 + 1);
649 }
650
e2286268
MC
651 if (TARGET_HARD_FLOAT)
652 {
653 /* Compute size of callee svaed floating-point registers. */
654 if (cfun->machine->callee_saved_last_fpr_regno != SP_REGNUM)
655 {
656 cfun->machine->callee_saved_fpr_regs_size
657 = 4 * (cfun->machine->callee_saved_last_fpr_regno
658 - cfun->machine->callee_saved_first_fpr_regno
659 + 1);
660 }
661 }
662
9304f876 663 /* Important: We need to make sure that
8a498f99
CJW
664 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
665 is 8-byte alignment.
666 If it is not, calculate the padding bytes. */
35da54a6 667 block_size = cfun->machine->fp_size
9304f876
CJW
668 + cfun->machine->gp_size
669 + cfun->machine->lp_size
c457f751 670 + cfun->machine->callee_saved_gpr_regs_size;
9304f876
CJW
671 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
672 {
c457f751 673 cfun->machine->callee_saved_area_gpr_padding_bytes
9304f876
CJW
674 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
675 }
676
677 /* If stack usage computation is required,
678 we need to provide the static stack size. */
679 if (flag_stack_usage_info)
680 {
681 current_function_static_stack_size
682 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
683 + cfun->machine->local_size
684 + cfun->machine->out_args_size;
685 }
686}
687
688/* Function to create a parallel rtx pattern
689 which presents stack push multiple behavior.
690 The overall concept are:
691 "push registers to memory",
692 "adjust stack pointer". */
4e9a2848 693static void
a6c7e777
MC
694nds32_emit_stack_push_multiple (unsigned Rb, unsigned Re,
695 bool save_fp_p, bool save_gp_p, bool save_lp_p,
696 bool vaarg_p)
9304f876 697{
a6c7e777 698 unsigned regno;
9304f876
CJW
699 int extra_count;
700 int num_use_regs;
701 int par_index;
702 int offset;
703
704 rtx reg;
705 rtx mem;
706 rtx push_rtx;
707 rtx adjust_sp_rtx;
708 rtx parallel_insn;
47e0e7d2 709 rtx dwarf;
9304f876
CJW
710
711 /* We need to provide a customized rtx which contains
712 necessary information for data analysis,
713 so we create a parallel rtx like this:
714 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
8a498f99
CJW
715 (reg:SI Rb))
716 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
717 (reg:SI Rb+1))
718 ...
719 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
720 (reg:SI Re))
721 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
722 (reg:SI FP_REGNUM))
723 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
724 (reg:SI GP_REGNUM))
725 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
726 (reg:SI LP_REGNUM))
727 (set (reg:SI SP_REGNUM)
728 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
9304f876
CJW
729
730 /* Calculate the number of registers that will be pushed. */
731 extra_count = 0;
a6c7e777 732 if (save_fp_p)
9304f876 733 extra_count++;
a6c7e777 734 if (save_gp_p)
9304f876 735 extra_count++;
a6c7e777 736 if (save_lp_p)
9304f876
CJW
737 extra_count++;
738 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
a6c7e777 739 if (Rb == SP_REGNUM && Re == SP_REGNUM)
9304f876
CJW
740 num_use_regs = extra_count;
741 else
a6c7e777 742 num_use_regs = Re - Rb + 1 + extra_count;
9304f876
CJW
743
744 /* In addition to used registers,
745 we need one more space for (set sp sp-x) rtx. */
746 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
747 rtvec_alloc (num_use_regs + 1));
748 par_index = 0;
749
750 /* Initialize offset and start to create push behavior. */
751 offset = -(num_use_regs * 4);
752
753 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
a6c7e777 754 for (regno = Rb; regno <= Re; regno++)
9304f876
CJW
755 {
756 /* Rb and Re may be SP_REGNUM.
8a498f99 757 We need to break this loop immediately. */
9304f876 758 if (regno == SP_REGNUM)
4e9a2848 759 break;
9304f876
CJW
760
761 reg = gen_rtx_REG (SImode, regno);
762 mem = gen_frame_mem (SImode, plus_constant (Pmode,
763 stack_pointer_rtx,
764 offset));
f7df4a84 765 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
766 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
767 RTX_FRAME_RELATED_P (push_rtx) = 1;
768 offset = offset + 4;
769 par_index++;
770 }
771
772 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
a6c7e777 773 if (save_fp_p)
9304f876
CJW
774 {
775 reg = gen_rtx_REG (SImode, FP_REGNUM);
776 mem = gen_frame_mem (SImode, plus_constant (Pmode,
777 stack_pointer_rtx,
778 offset));
f7df4a84 779 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
780 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
781 RTX_FRAME_RELATED_P (push_rtx) = 1;
782 offset = offset + 4;
783 par_index++;
784 }
a6c7e777 785 if (save_gp_p)
9304f876
CJW
786 {
787 reg = gen_rtx_REG (SImode, GP_REGNUM);
788 mem = gen_frame_mem (SImode, plus_constant (Pmode,
789 stack_pointer_rtx,
790 offset));
f7df4a84 791 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
792 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
793 RTX_FRAME_RELATED_P (push_rtx) = 1;
794 offset = offset + 4;
795 par_index++;
796 }
a6c7e777 797 if (save_lp_p)
9304f876
CJW
798 {
799 reg = gen_rtx_REG (SImode, LP_REGNUM);
800 mem = gen_frame_mem (SImode, plus_constant (Pmode,
801 stack_pointer_rtx,
802 offset));
f7df4a84 803 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
804 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
805 RTX_FRAME_RELATED_P (push_rtx) = 1;
806 offset = offset + 4;
807 par_index++;
808 }
809
810 /* Create (set sp sp-x). */
811
812 /* We need to re-calculate the offset value again for adjustment. */
813 offset = -(num_use_regs * 4);
814 adjust_sp_rtx
f7df4a84 815 = gen_rtx_SET (stack_pointer_rtx,
9304f876
CJW
816 plus_constant (Pmode, stack_pointer_rtx, offset));
817 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
818 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
819
4e9a2848
CJW
820 parallel_insn = emit_insn (parallel_insn);
821
822 /* The insn rtx 'parallel_insn' will change frame layout.
823 We need to use RTX_FRAME_RELATED_P so that GCC is able to
824 generate CFI (Call Frame Information) stuff. */
825 RTX_FRAME_RELATED_P (parallel_insn) = 1;
47e0e7d2
CJW
826
827 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
828 since we will not restore those register at epilogue. */
829 if (vaarg_p)
830 {
831 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
832 copy_rtx (adjust_sp_rtx), NULL_RTX);
833 REG_NOTES (parallel_insn) = dwarf;
834 }
9304f876
CJW
835}
836
837/* Function to create a parallel rtx pattern
838 which presents stack pop multiple behavior.
839 The overall concept are:
840 "pop registers from memory",
841 "adjust stack pointer". */
4e9a2848 842static void
a6c7e777
MC
843nds32_emit_stack_pop_multiple (unsigned Rb, unsigned Re,
844 bool save_fp_p, bool save_gp_p, bool save_lp_p)
9304f876 845{
a6c7e777 846 unsigned regno;
9304f876
CJW
847 int extra_count;
848 int num_use_regs;
849 int par_index;
850 int offset;
851
852 rtx reg;
853 rtx mem;
854 rtx pop_rtx;
855 rtx adjust_sp_rtx;
856 rtx parallel_insn;
4e9a2848 857 rtx dwarf = NULL_RTX;
9304f876
CJW
858
859 /* We need to provide a customized rtx which contains
860 necessary information for data analysis,
861 so we create a parallel rtx like this:
862 (parallel [(set (reg:SI Rb)
8a498f99
CJW
863 (mem (reg:SI SP_REGNUM)))
864 (set (reg:SI Rb+1)
865 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
866 ...
867 (set (reg:SI Re)
868 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
869 (set (reg:SI FP_REGNUM)
870 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
871 (set (reg:SI GP_REGNUM)
872 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
873 (set (reg:SI LP_REGNUM)
874 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
875 (set (reg:SI SP_REGNUM)
876 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
9304f876
CJW
877
878 /* Calculate the number of registers that will be poped. */
879 extra_count = 0;
a6c7e777 880 if (save_fp_p)
9304f876 881 extra_count++;
a6c7e777 882 if (save_gp_p)
9304f876 883 extra_count++;
a6c7e777 884 if (save_lp_p)
9304f876
CJW
885 extra_count++;
886 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
a6c7e777 887 if (Rb == SP_REGNUM && Re == SP_REGNUM)
9304f876
CJW
888 num_use_regs = extra_count;
889 else
a6c7e777 890 num_use_regs = Re - Rb + 1 + extra_count;
9304f876
CJW
891
892 /* In addition to used registers,
893 we need one more space for (set sp sp+x) rtx. */
894 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
895 rtvec_alloc (num_use_regs + 1));
896 par_index = 0;
897
898 /* Initialize offset and start to create pop behavior. */
899 offset = 0;
900
901 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
a6c7e777 902 for (regno = Rb; regno <= Re; regno++)
9304f876
CJW
903 {
904 /* Rb and Re may be SP_REGNUM.
8a498f99 905 We need to break this loop immediately. */
9304f876 906 if (regno == SP_REGNUM)
4e9a2848 907 break;
9304f876
CJW
908
909 reg = gen_rtx_REG (SImode, regno);
910 mem = gen_frame_mem (SImode, plus_constant (Pmode,
911 stack_pointer_rtx,
912 offset));
f7df4a84 913 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
914 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
915 RTX_FRAME_RELATED_P (pop_rtx) = 1;
916 offset = offset + 4;
917 par_index++;
4e9a2848
CJW
918
919 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
920 }
921
922 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
a6c7e777 923 if (save_fp_p)
9304f876
CJW
924 {
925 reg = gen_rtx_REG (SImode, FP_REGNUM);
926 mem = gen_frame_mem (SImode, plus_constant (Pmode,
927 stack_pointer_rtx,
928 offset));
f7df4a84 929 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
930 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
931 RTX_FRAME_RELATED_P (pop_rtx) = 1;
932 offset = offset + 4;
933 par_index++;
4e9a2848
CJW
934
935 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876 936 }
a6c7e777 937 if (save_gp_p)
9304f876
CJW
938 {
939 reg = gen_rtx_REG (SImode, GP_REGNUM);
940 mem = gen_frame_mem (SImode, plus_constant (Pmode,
941 stack_pointer_rtx,
942 offset));
f7df4a84 943 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
944 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
945 RTX_FRAME_RELATED_P (pop_rtx) = 1;
946 offset = offset + 4;
947 par_index++;
4e9a2848
CJW
948
949 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876 950 }
a6c7e777 951 if (save_lp_p)
9304f876
CJW
952 {
953 reg = gen_rtx_REG (SImode, LP_REGNUM);
954 mem = gen_frame_mem (SImode, plus_constant (Pmode,
955 stack_pointer_rtx,
956 offset));
f7df4a84 957 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
958 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
959 RTX_FRAME_RELATED_P (pop_rtx) = 1;
960 offset = offset + 4;
961 par_index++;
4e9a2848
CJW
962
963 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
964 }
965
966 /* Create (set sp sp+x). */
967
968 /* The offset value is already in place. No need to re-calculate it. */
969 adjust_sp_rtx
f7df4a84 970 = gen_rtx_SET (stack_pointer_rtx,
9304f876
CJW
971 plus_constant (Pmode, stack_pointer_rtx, offset));
972 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
9304f876 973
4e9a2848
CJW
974 /* Tell gcc we adjust SP in this insn. */
975 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
976
977 parallel_insn = emit_insn (parallel_insn);
978
979 /* The insn rtx 'parallel_insn' will change frame layout.
980 We need to use RTX_FRAME_RELATED_P so that GCC is able to
981 generate CFI (Call Frame Information) stuff. */
982 RTX_FRAME_RELATED_P (parallel_insn) = 1;
983
984 /* Add CFI info by manual. */
985 REG_NOTES (parallel_insn) = dwarf;
9304f876
CJW
986}
987
988/* Function to create a parallel rtx pattern
989 which presents stack v3push behavior.
990 The overall concept are:
991 "push registers to memory",
992 "adjust stack pointer". */
88437f39 993static void
a6c7e777
MC
994nds32_emit_stack_v3push (unsigned Rb,
995 unsigned Re,
996 unsigned imm8u)
9304f876 997{
a6c7e777 998 unsigned regno;
9304f876
CJW
999 int num_use_regs;
1000 int par_index;
1001 int offset;
1002
1003 rtx reg;
1004 rtx mem;
1005 rtx push_rtx;
1006 rtx adjust_sp_rtx;
1007 rtx parallel_insn;
1008
1009 /* We need to provide a customized rtx which contains
1010 necessary information for data analysis,
1011 so we create a parallel rtx like this:
88437f39 1012 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
8a498f99
CJW
1013 (reg:SI Rb))
1014 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
1015 (reg:SI Rb+1))
1016 ...
1017 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
1018 (reg:SI Re))
1019 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
1020 (reg:SI FP_REGNUM))
1021 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
1022 (reg:SI GP_REGNUM))
1023 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
1024 (reg:SI LP_REGNUM))
1025 (set (reg:SI SP_REGNUM)
1026 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
9304f876
CJW
1027
1028 /* Calculate the number of registers that will be pushed.
1029 Since $fp, $gp, and $lp is always pushed with v3push instruction,
1030 we need to count these three registers.
1031 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1032 So there is no need to worry about Rb=Re=SP_REGNUM case. */
a6c7e777 1033 num_use_regs = Re - Rb + 1 + 3;
9304f876
CJW
1034
1035 /* In addition to used registers,
1036 we need one more space for (set sp sp-x-imm8u) rtx. */
1037 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
1038 rtvec_alloc (num_use_regs + 1));
1039 par_index = 0;
1040
1041 /* Initialize offset and start to create push behavior. */
1042 offset = -(num_use_regs * 4);
1043
1044 /* Create (set mem regX) from Rb, Rb+1 up to Re.
1045 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1046 So there is no need to worry about Rb=Re=SP_REGNUM case. */
a6c7e777 1047 for (regno = Rb; regno <= Re; regno++)
9304f876
CJW
1048 {
1049 reg = gen_rtx_REG (SImode, regno);
1050 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1051 stack_pointer_rtx,
1052 offset));
f7df4a84 1053 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
1054 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1055 RTX_FRAME_RELATED_P (push_rtx) = 1;
1056 offset = offset + 4;
1057 par_index++;
1058 }
1059
1060 /* Create (set mem fp). */
1061 reg = gen_rtx_REG (SImode, FP_REGNUM);
1062 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1063 stack_pointer_rtx,
1064 offset));
f7df4a84 1065 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
1066 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1067 RTX_FRAME_RELATED_P (push_rtx) = 1;
1068 offset = offset + 4;
1069 par_index++;
1070 /* Create (set mem gp). */
1071 reg = gen_rtx_REG (SImode, GP_REGNUM);
1072 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1073 stack_pointer_rtx,
1074 offset));
f7df4a84 1075 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
1076 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1077 RTX_FRAME_RELATED_P (push_rtx) = 1;
1078 offset = offset + 4;
1079 par_index++;
1080 /* Create (set mem lp). */
1081 reg = gen_rtx_REG (SImode, LP_REGNUM);
1082 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1083 stack_pointer_rtx,
1084 offset));
f7df4a84 1085 push_rtx = gen_rtx_SET (mem, reg);
9304f876
CJW
1086 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
1087 RTX_FRAME_RELATED_P (push_rtx) = 1;
1088 offset = offset + 4;
1089 par_index++;
1090
1091 /* Create (set sp sp-x-imm8u). */
1092
1093 /* We need to re-calculate the offset value again for adjustment. */
1094 offset = -(num_use_regs * 4);
1095 adjust_sp_rtx
f7df4a84 1096 = gen_rtx_SET (stack_pointer_rtx,
9304f876
CJW
1097 plus_constant (Pmode,
1098 stack_pointer_rtx,
a6c7e777 1099 offset - imm8u));
9304f876
CJW
1100 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
1101 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
1102
88437f39
CJW
1103 parallel_insn = emit_insn (parallel_insn);
1104
1105 /* The insn rtx 'parallel_insn' will change frame layout.
1106 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1107 generate CFI (Call Frame Information) stuff. */
1108 RTX_FRAME_RELATED_P (parallel_insn) = 1;
9304f876
CJW
1109}
1110
1111/* Function to create a parallel rtx pattern
1112 which presents stack v3pop behavior.
1113 The overall concept are:
1114 "pop registers from memory",
1115 "adjust stack pointer". */
88437f39 1116static void
a6c7e777
MC
1117nds32_emit_stack_v3pop (unsigned Rb,
1118 unsigned Re,
1119 unsigned imm8u)
9304f876 1120{
a6c7e777 1121 unsigned regno;
9304f876
CJW
1122 int num_use_regs;
1123 int par_index;
1124 int offset;
1125
1126 rtx reg;
1127 rtx mem;
1128 rtx pop_rtx;
1129 rtx adjust_sp_rtx;
1130 rtx parallel_insn;
88437f39 1131 rtx dwarf = NULL_RTX;
9304f876
CJW
1132
1133 /* We need to provide a customized rtx which contains
1134 necessary information for data analysis,
1135 so we create a parallel rtx like this:
1136 (parallel [(set (reg:SI Rb)
8a498f99
CJW
1137 (mem (reg:SI SP_REGNUM)))
1138 (set (reg:SI Rb+1)
1139 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
1140 ...
1141 (set (reg:SI Re)
1142 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
1143 (set (reg:SI FP_REGNUM)
1144 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
1145 (set (reg:SI GP_REGNUM)
1146 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
1147 (set (reg:SI LP_REGNUM)
1148 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
1149 (set (reg:SI SP_REGNUM)
1150 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
9304f876
CJW
1151
1152 /* Calculate the number of registers that will be poped.
1153 Since $fp, $gp, and $lp is always poped with v3pop instruction,
1154 we need to count these three registers.
1155 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1156 So there is no need to worry about Rb=Re=SP_REGNUM case. */
a6c7e777 1157 num_use_regs = Re - Rb + 1 + 3;
9304f876
CJW
1158
1159 /* In addition to used registers,
1160 we need one more space for (set sp sp+x+imm8u) rtx. */
1161 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
1162 rtvec_alloc (num_use_regs + 1));
1163 par_index = 0;
1164
1165 /* Initialize offset and start to create pop behavior. */
1166 offset = 0;
1167
1168 /* Create (set regX mem) from Rb, Rb+1 up to Re.
1169 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1170 So there is no need to worry about Rb=Re=SP_REGNUM case. */
a6c7e777 1171 for (regno = Rb; regno <= Re; regno++)
9304f876
CJW
1172 {
1173 reg = gen_rtx_REG (SImode, regno);
1174 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1175 stack_pointer_rtx,
1176 offset));
f7df4a84 1177 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
1178 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1179 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1180 offset = offset + 4;
1181 par_index++;
88437f39
CJW
1182
1183 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
1184 }
1185
1186 /* Create (set fp mem). */
1187 reg = gen_rtx_REG (SImode, FP_REGNUM);
1188 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1189 stack_pointer_rtx,
1190 offset));
f7df4a84 1191 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
1192 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1193 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1194 offset = offset + 4;
1195 par_index++;
88437f39
CJW
1196 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1197
9304f876
CJW
1198 /* Create (set gp mem). */
1199 reg = gen_rtx_REG (SImode, GP_REGNUM);
1200 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1201 stack_pointer_rtx,
1202 offset));
f7df4a84 1203 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
1204 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1205 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1206 offset = offset + 4;
1207 par_index++;
88437f39
CJW
1208 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
1209
9304f876
CJW
1210 /* Create (set lp mem ). */
1211 reg = gen_rtx_REG (SImode, LP_REGNUM);
1212 mem = gen_frame_mem (SImode, plus_constant (Pmode,
1213 stack_pointer_rtx,
1214 offset));
f7df4a84 1215 pop_rtx = gen_rtx_SET (reg, mem);
9304f876
CJW
1216 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
1217 RTX_FRAME_RELATED_P (pop_rtx) = 1;
1218 offset = offset + 4;
1219 par_index++;
88437f39 1220 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
9304f876
CJW
1221
1222 /* Create (set sp sp+x+imm8u). */
1223
1224 /* The offset value is already in place. No need to re-calculate it. */
1225 adjust_sp_rtx
f7df4a84 1226 = gen_rtx_SET (stack_pointer_rtx,
9304f876
CJW
1227 plus_constant (Pmode,
1228 stack_pointer_rtx,
a6c7e777 1229 offset + imm8u));
9304f876 1230 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
9304f876 1231
a6c7e777
MC
1232 if (frame_pointer_needed)
1233 {
1234 /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp)
1235 (const_int 0))
1236 mean reset frame pointer to $sp and reset to offset 0. */
1237 rtx cfa_adjust_rtx = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1238 const0_rtx);
1239 dwarf = alloc_reg_note (REG_CFA_DEF_CFA, cfa_adjust_rtx, dwarf);
1240 }
1241 else
1242 {
1243 /* Tell gcc we adjust SP in this insn. */
1244 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA,
1245 copy_rtx (adjust_sp_rtx), dwarf);
1246 }
88437f39
CJW
1247
1248 parallel_insn = emit_insn (parallel_insn);
1249
1250 /* The insn rtx 'parallel_insn' will change frame layout.
1251 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1252 generate CFI (Call Frame Information) stuff. */
1253 RTX_FRAME_RELATED_P (parallel_insn) = 1;
1254
1255 /* Add CFI info by manual. */
1256 REG_NOTES (parallel_insn) = dwarf;
9304f876
CJW
1257}
1258
9304f876
CJW
1259/* Function that may creates more instructions
1260 for large value on adjusting stack pointer.
1261
1262 In nds32 target, 'addi' can be used for stack pointer
1263 adjustment in prologue/epilogue stage.
1264 However, sometimes there are too many local variables so that
1265 the adjustment value is not able to be fit in the 'addi' instruction.
1266 One solution is to move value into a register
1267 and then use 'add' instruction.
a6c7e777
MC
1268 In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */
1269static void
1270nds32_emit_adjust_frame (rtx to_reg, rtx from_reg, int adjust_value)
9304f876 1271{
9304f876 1272 rtx tmp_reg;
a6c7e777
MC
1273 rtx frame_adjust_insn;
1274 rtx adjust_value_rtx = GEN_INT (adjust_value);
9304f876 1275
a6c7e777
MC
1276 if (adjust_value == 0)
1277 return;
1278
1279 if (!satisfies_constraint_Is15 (adjust_value_rtx))
9304f876
CJW
1280 {
1281 /* The value is not able to fit in single addi instruction.
8a498f99
CJW
1282 Create more instructions of moving value into a register
1283 and then add stack pointer with it. */
9304f876
CJW
1284
1285 /* $r15 is going to be temporary register to hold the value. */
1286 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
1287
1288 /* Create one more instruction to move value
8a498f99 1289 into the temporary register. */
a6c7e777 1290 emit_move_insn (tmp_reg, adjust_value_rtx);
9304f876
CJW
1291
1292 /* Create new 'add' rtx. */
a6c7e777
MC
1293 frame_adjust_insn = gen_addsi3 (to_reg,
1294 from_reg,
1295 tmp_reg);
9304f876 1296 /* Emit rtx into insn list and receive its transformed insn rtx. */
a6c7e777 1297 frame_adjust_insn = emit_insn (frame_adjust_insn);
9304f876 1298
a6c7e777
MC
1299 /* Because (tmp_reg <- full_value) may be split into two
1300 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1301 We need to construct another (sp <- sp + full_value)
1302 and then insert it into sp_adjust_insn's reg note to
1303 represent a frame related expression.
1304 GCC knows how to refer it and output debug information. */
9304f876 1305
a6c7e777
MC
1306 rtx plus_rtx;
1307 rtx set_rtx;
9304f876 1308
a6c7e777
MC
1309 plus_rtx = plus_constant (Pmode, from_reg, adjust_value);
1310 set_rtx = gen_rtx_SET (to_reg, plus_rtx);
1311 add_reg_note (frame_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
9304f876
CJW
1312 }
1313 else
1314 {
a6c7e777
MC
1315 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
1316 frame_adjust_insn = gen_addsi3 (to_reg,
1317 from_reg,
1318 adjust_value_rtx);
1319 /* Emit rtx into instructions list and receive INSN rtx form. */
1320 frame_adjust_insn = emit_insn (frame_adjust_insn);
9304f876 1321 }
a6c7e777
MC
1322
1323 /* The insn rtx 'sp_adjust_insn' will change frame layout.
1324 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1325 generate CFI (Call Frame Information) stuff. */
1326 RTX_FRAME_RELATED_P (frame_adjust_insn) = 1;
9304f876
CJW
1327}
1328
1329/* Return true if MODE/TYPE need double word alignment. */
1330static bool
ef4bddc2 1331nds32_needs_double_word_align (machine_mode mode, const_tree type)
9304f876
CJW
1332{
1333 unsigned int align;
1334
634bdae9
CJW
1335 /* Pick up the alignment according to the mode or type. */
1336 align = NDS32_MODE_TYPE_ALIGN (mode, type);
9304f876
CJW
1337
1338 return (align > PARM_BOUNDARY);
1339}
1340
1341/* Return true if FUNC is a naked function. */
810f736f
CJW
1342static bool
1343nds32_naked_function_p (tree func)
9304f876
CJW
1344{
1345 tree t;
1346
1347 if (TREE_CODE (func) != FUNCTION_DECL)
1348 abort ();
1349
1350 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1351
1352 return (t != NULL_TREE);
1353}
1354
1355/* Function that check if 'X' is a valid address register.
1356 The variable 'STRICT' is very important to
1357 make decision for register number.
1358
1359 STRICT : true
1360 => We are in reload pass or after reload pass.
8a498f99 1361 The register number should be strictly limited in general registers.
9304f876
CJW
1362
1363 STRICT : false
1364 => Before reload pass, we are free to use any register number. */
1365static bool
1366nds32_address_register_rtx_p (rtx x, bool strict)
1367{
1368 int regno;
1369
1370 if (GET_CODE (x) != REG)
1371 return false;
1372
1373 regno = REGNO (x);
1374
1375 if (strict)
1376 return REGNO_OK_FOR_BASE_P (regno);
1377 else
1378 return true;
1379}
1380
1381/* Function that check if 'INDEX' is valid to be a index rtx for address.
1382
1383 OUTER_MODE : Machine mode of outer address rtx.
8a498f99 1384 INDEX : Check if this rtx is valid to be a index for address.
9304f876
CJW
1385 STRICT : If it is true, we are in reload pass or after reload pass. */
1386static bool
ef4bddc2 1387nds32_legitimate_index_p (machine_mode outer_mode,
9304f876
CJW
1388 rtx index,
1389 bool strict)
1390{
1391 int regno;
1392 rtx op0;
1393 rtx op1;
1394
1395 switch (GET_CODE (index))
1396 {
1397 case REG:
1398 regno = REGNO (index);
1399 /* If we are in reload pass or after reload pass,
8a498f99 1400 we need to limit it to general register. */
9304f876
CJW
1401 if (strict)
1402 return REGNO_OK_FOR_INDEX_P (regno);
1403 else
1404 return true;
1405
1406 case CONST_INT:
1407 /* The alignment of the integer value is determined by 'outer_mode'. */
e2286268 1408 switch (GET_MODE_SIZE (outer_mode))
9304f876 1409 {
e2286268 1410 case 1:
9304f876 1411 /* Further check if the value is legal for the 'outer_mode'. */
e2286268
MC
1412 if (satisfies_constraint_Is15 (index))
1413 return true;
1414 break;
9304f876 1415
e2286268 1416 case 2:
9304f876 1417 /* Further check if the value is legal for the 'outer_mode'. */
e2286268
MC
1418 if (satisfies_constraint_Is16 (index))
1419 {
5f2a98c3
CJW
1420 /* If it is not under strictly aligned situation,
1421 we can return true without checking alignment. */
1422 if (!cfun->machine->strict_aligned_p)
1423 return true;
e2286268 1424 /* Make sure address is half word alignment. */
5f2a98c3 1425 else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
e2286268
MC
1426 return true;
1427 }
1428 break;
9304f876 1429
e2286268 1430 case 4:
9304f876 1431 /* Further check if the value is legal for the 'outer_mode'. */
e2286268
MC
1432 if (satisfies_constraint_Is17 (index))
1433 {
1434 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
1435 {
1436 if (!satisfies_constraint_Is14 (index))
1437 return false;
1438 }
1439
5f2a98c3
CJW
1440 /* If it is not under strictly aligned situation,
1441 we can return true without checking alignment. */
1442 if (!cfun->machine->strict_aligned_p)
1443 return true;
e2286268 1444 /* Make sure address is word alignment. */
5f2a98c3 1445 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
e2286268
MC
1446 return true;
1447 }
1448 break;
9304f876 1449
e2286268
MC
1450 case 8:
1451 if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1452 SImode)))
1453 {
1454 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
1455 {
1456 if (!satisfies_constraint_Is14 (index))
1457 return false;
1458 }
1459
5f2a98c3
CJW
1460 /* If it is not under strictly aligned situation,
1461 we can return true without checking alignment. */
1462 if (!cfun->machine->strict_aligned_p)
1463 return true;
e2286268
MC
1464 /* Make sure address is word alignment.
1465 Currently we do not have 64-bit load/store yet,
1466 so we will use two 32-bit load/store instructions to do
1467 memory access and they are single word alignment. */
5f2a98c3 1468 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
e2286268
MC
1469 return true;
1470 }
1471 break;
9304f876 1472
e2286268
MC
1473 default:
1474 return false;
9304f876
CJW
1475 }
1476
1477 return false;
1478
1479 case MULT:
1480 op0 = XEXP (index, 0);
1481 op1 = XEXP (index, 1);
1482
1483 if (REG_P (op0) && CONST_INT_P (op1))
1484 {
1485 int multiplier;
1486 multiplier = INTVAL (op1);
1487
f62a2af5
CJW
1488 /* We only allow (mult reg const_int_1), (mult reg const_int_2),
1489 (mult reg const_int_4) or (mult reg const_int_8). */
1490 if (multiplier != 1 && multiplier != 2
1491 && multiplier != 4 && multiplier != 8)
9304f876
CJW
1492 return false;
1493
1494 regno = REGNO (op0);
1495 /* Limit it in general registers if we are
1496 in reload pass or after reload pass. */
1497 if(strict)
1498 return REGNO_OK_FOR_INDEX_P (regno);
1499 else
1500 return true;
1501 }
1502
1503 return false;
1504
1505 case ASHIFT:
1506 op0 = XEXP (index, 0);
1507 op1 = XEXP (index, 1);
1508
1509 if (REG_P (op0) && CONST_INT_P (op1))
1510 {
1511 int sv;
1512 /* op1 is already the sv value for use to do left shift. */
1513 sv = INTVAL (op1);
1514
1515 /* We only allow (ashift reg const_int_0)
f62a2af5
CJW
1516 or (ashift reg const_int_1) or (ashift reg const_int_2) or
1517 (ashift reg const_int_3). */
1518 if (sv != 0 && sv != 1 && sv !=2 && sv != 3)
9304f876
CJW
1519 return false;
1520
1521 regno = REGNO (op0);
1522 /* Limit it in general registers if we are
1523 in reload pass or after reload pass. */
1524 if(strict)
1525 return REGNO_OK_FOR_INDEX_P (regno);
1526 else
1527 return true;
1528 }
1529
1530 return false;
1531
1532 default:
1533 return false;
1534 }
1535}
1536
c4d8d050
CJW
1537static void
1538nds32_register_pass (
1539 rtl_opt_pass *(*make_pass_func) (gcc::context *),
1540 enum pass_positioning_ops pass_pos,
1541 const char *ref_pass_name)
1542{
1543 opt_pass *new_opt_pass = make_pass_func (g);
1544
1545 struct register_pass_info insert_pass =
1546 {
1547 new_opt_pass, /* pass */
1548 ref_pass_name, /* reference_pass_name */
1549 1, /* ref_pass_instance_number */
1550 pass_pos /* po_op */
1551 };
1552
1553 register_pass (&insert_pass);
1554}
1555
1556/* This function is called from nds32_option_override ().
1557 All new passes should be registered here. */
1558static void
1559nds32_register_passes (void)
1560{
1561 nds32_register_pass (
1562 make_pass_nds32_relax_opt,
1563 PASS_POS_INSERT_AFTER,
1564 "mach");
1565}
1566
9304f876
CJW
1567/* ------------------------------------------------------------------------ */
1568
1569/* PART 3: Implement target hook stuff definitions. */
e2286268
MC
1570\f
1571
a5876228
CJW
1572/* Computing the Length of an Insn.
1573 Modifies the length assigned to instruction INSN.
1574 LEN is the initially computed length of the insn. */
1575int
1576nds32_adjust_insn_length (rtx_insn *insn, int length)
1577{
1578 int adjust_value = 0;
1579 switch (recog_memoized (insn))
1580 {
1581 case CODE_FOR_call_internal:
1582 case CODE_FOR_call_value_internal:
1583 {
43fa41c1
CJW
1584 if (NDS32_ALIGN_P ())
1585 {
1586 rtx_insn *next_insn = next_active_insn (insn);
1587 if (next_insn && get_attr_length (next_insn) != 2)
1588 adjust_value += 2;
1589 }
a5876228
CJW
1590 /* We need insert a nop after a noretun function call
1591 to prevent software breakpoint corrupt the next function. */
1592 if (find_reg_note (insn, REG_NORETURN, NULL_RTX))
1593 {
1594 if (TARGET_16_BIT)
1595 adjust_value += 2;
1596 else
1597 adjust_value += 4;
1598 }
1599 }
1600 return length + adjust_value;
1601
1602 default:
1603 return length;
1604 }
1605}
1606
5f2a98c3
CJW
1607/* Storage Layout. */
1608
1609/* This function will be called just before expansion into rtl. */
1610static void
1611nds32_expand_to_rtl_hook (void)
1612{
1613 /* We need to set strictly aligned situation.
1614 After that, the memory address checking in nds32_legitimate_address_p()
1615 will take alignment offset into consideration so that it will not create
1616 unaligned [base + offset] access during the rtl optimization. */
1617 cfun->machine->strict_aligned_p = 1;
1618}
1619
1620\f
e2286268
MC
1621/* Register Usage. */
1622
1623static void
1624nds32_conditional_register_usage (void)
1625{
1626 int regno;
1627
1628 if (TARGET_HARD_FLOAT)
1629 {
1630 for (regno = NDS32_FIRST_FPR_REGNUM;
1631 regno <= NDS32_LAST_FPR_REGNUM; regno++)
1632 {
1633 fixed_regs[regno] = 0;
1634 if (regno < NDS32_FIRST_FPR_REGNUM + NDS32_MAX_FPR_REGS_FOR_ARGS)
1635 call_used_regs[regno] = 1;
1636 else if (regno >= NDS32_FIRST_FPR_REGNUM + 22
1637 && regno < NDS32_FIRST_FPR_REGNUM + 48)
1638 call_used_regs[regno] = 1;
1639 else
1640 call_used_regs[regno] = 0;
1641 }
1642 }
1643 else if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
1644 {
1645 for (regno = NDS32_FIRST_FPR_REGNUM;
1646 regno <= NDS32_LAST_FPR_REGNUM;
1647 regno++)
1648 fixed_regs[regno] = 0;
1649 }
1650}
1651
9304f876
CJW
1652\f
1653/* Register Classes. */
1654
1655static unsigned char
1656nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
ef4bddc2 1657 machine_mode mode)
9304f876
CJW
1658{
1659 /* Return the maximum number of consecutive registers
1660 needed to represent "mode" in a register of "rclass". */
1661 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1662}
1663
1664static int
1665nds32_register_priority (int hard_regno)
1666{
1667 /* Encourage to use r0-r7 for LRA when optimize for size. */
6a5a7ee3
CJW
1668 if (optimize_size)
1669 {
1670 if (hard_regno < 8)
1671 return 4;
1672 else if (hard_regno < 16)
1673 return 3;
1674 else if (hard_regno < 28)
1675 return 2;
1676 else
1677 return 1;
1678 }
1679 else
1680 {
1681 if (hard_regno > 27)
1682 return 1;
1683 else
1684 return 4;
1685 }
9304f876
CJW
1686}
1687
e2286268
MC
1688static bool
1689nds32_can_change_mode_class (machine_mode from,
1690 machine_mode to,
1691 reg_class_t rclass)
1692{
1693 /* Don't spill double-precision register to two singal-precision
1694 registers */
1695 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
1696 && GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
1697 {
1698 return !reg_classes_intersect_p (rclass, FP_REGS);
1699 }
1700
1701 return true;
1702}
1703
9304f876
CJW
1704\f
1705/* Stack Layout and Calling Conventions. */
1706
1707/* There are three kinds of pointer concepts using in GCC compiler:
1708
1709 frame pointer: A pointer to the first location of local variables.
1710 stack pointer: A pointer to the top of a stack frame.
1711 argument pointer: A pointer to the incoming arguments.
1712
1713 In nds32 target calling convention, we are using 8-byte alignment.
1714 Besides, we would like to have each stack frame of a function includes:
1715
1716 [Block A]
1717 1. previous hard frame pointer
1718 2. return address
1719 3. callee-saved registers
1720 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
8a498f99
CJW
1721 and save it at
1722 cfun->machine->callee_saved_area_padding_bytes)
9304f876
CJW
1723
1724 [Block B]
1725 1. local variables
1726 2. spilling location
1727 3. <padding bytes> (it will be calculated by GCC itself)
1728 4. incoming arguments
1729 5. <padding bytes> (it will be calculated by GCC itself)
1730
1731 [Block C]
1732 1. <padding bytes> (it will be calculated by GCC itself)
1733 2. outgoing arguments
1734
1735 We 'wrap' these blocks together with
1736 hard frame pointer ($r28) and stack pointer ($r31).
1737 By applying the basic frame/stack/argument pointers concept,
1738 the layout of a stack frame shoule be like this:
1739
8a498f99 1740 | |
9304f876 1741 old stack pointer -> ----
8a498f99
CJW
1742 | | \
1743 | | saved arguments for
1744 | | vararg functions
1745 | | /
9304f876
CJW
1746 hard frame pointer -> --
1747 & argument pointer | | \
8a498f99
CJW
1748 | | previous hardware frame pointer
1749 | | return address
1750 | | callee-saved registers
1751 | | /
1752 frame pointer -> --
1753 | | \
1754 | | local variables
1755 | | and incoming arguments
1756 | | /
1757 --
1758 | | \
1759 | | outgoing
1760 | | arguments
1761 | | /
1762 stack pointer -> ----
9304f876
CJW
1763
1764 $SFP and $AP are used to represent frame pointer and arguments pointer,
1765 which will be both eliminated as hard frame pointer. */
1766
1767/* -- Eliminating Frame Pointer and Arg Pointer. */
1768
19ac960a
CJW
1769static bool
1770nds32_can_eliminate (const int from_reg, const int to_reg)
9304f876
CJW
1771{
1772 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1773 return true;
1774
1775 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1776 return true;
1777
1778 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1779 return true;
1780
1781 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1782 return true;
1783
1784 return false;
1785}
1786
1787/* -- Passing Arguments in Registers. */
1788
1789static rtx
ef4bddc2 1790nds32_function_arg (cumulative_args_t ca, machine_mode mode,
9304f876
CJW
1791 const_tree type, bool named)
1792{
7f6cd86b 1793 unsigned int regno;
9304f876
CJW
1794 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1795
1796 /* The last time this hook is called,
1797 it is called with MODE == VOIDmode. */
1798 if (mode == VOIDmode)
1799 return NULL_RTX;
1800
7f6cd86b 1801 /* For nameless arguments, we need to take care it individually. */
9304f876 1802 if (!named)
9304f876 1803 {
7f6cd86b 1804 /* If we are under hard float abi, we have arguments passed on the
8a498f99 1805 stack and all situation can be handled by GCC itself. */
7f6cd86b
CJW
1806 if (TARGET_HARD_FLOAT)
1807 return NULL_RTX;
1808
1809 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1810 {
1811 /* If we still have enough registers to pass argument, pick up
1812 next available register number. */
1813 regno
1814 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1815 return gen_rtx_REG (mode, regno);
1816 }
634bdae9 1817
9304f876 1818 /* No register available, return NULL_RTX.
8a498f99 1819 The compiler will use stack to pass argument instead. */
9304f876
CJW
1820 return NULL_RTX;
1821 }
7f6cd86b
CJW
1822
1823 /* The following is to handle named argument.
1824 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1825 are different. */
1826 if (TARGET_HARD_FLOAT)
1827 {
e2286268
MC
1828 /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR
1829 to pass argument. We have to further check TYPE and MODE so
1830 that we can determine which kind of register we shall use. */
1831
1832 /* Note that we need to pass argument entirely in registers under
1833 hard float abi. */
1834 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1835 && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum->fpr_offset, mode, type))
1836 {
1837 /* Pick up the next available FPR register number. */
1838 regno
1839 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type);
1840 return gen_rtx_REG (mode, regno);
1841 }
1842 else if (GET_MODE_CLASS (mode) != MODE_FLOAT
1843 && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1844 {
1845 /* Pick up the next available GPR register number. */
1846 regno
1847 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1848 return gen_rtx_REG (mode, regno);
1849 }
7f6cd86b
CJW
1850 }
1851 else
1852 {
1853 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
8a498f99
CJW
1854 argument. Since we allow to pass argument partially in registers,
1855 we can just return it if there are still registers available. */
7f6cd86b
CJW
1856 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum->gpr_offset, mode, type))
1857 {
1858 /* Pick up the next available register number. */
1859 regno
1860 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type);
1861 return gen_rtx_REG (mode, regno);
1862 }
1863
1864 }
1865
1866 /* No register available, return NULL_RTX.
1867 The compiler will use stack to pass argument instead. */
1868 return NULL_RTX;
9304f876
CJW
1869}
1870
d40f3c40 1871static bool
ef4bddc2 1872nds32_must_pass_in_stack (machine_mode mode, const_tree type)
d40f3c40
CJW
1873{
1874 /* Return true if a type must be passed in memory.
1875 If it is NOT using hard float abi, small aggregates can be
1876 passed in a register even we are calling a variadic function.
1877 So there is no need to take padding into consideration. */
1878 if (TARGET_HARD_FLOAT)
1879 return must_pass_in_stack_var_size_or_pad (mode, type);
1880 else
1881 return must_pass_in_stack_var_size (mode, type);
1882}
1883
650fc469 1884static int
ef4bddc2 1885nds32_arg_partial_bytes (cumulative_args_t ca, machine_mode mode,
650fc469
CJW
1886 tree type, bool named ATTRIBUTE_UNUSED)
1887{
1888 /* Returns the number of bytes at the beginning of an argument that
1889 must be put in registers. The value must be zero for arguments that are
1890 passed entirely in registers or that are entirely pushed on the stack.
1891 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1892 first register to be used by the caller for this argument. */
1893 unsigned int needed_reg_count;
1894 unsigned int remaining_reg_count;
1895 CUMULATIVE_ARGS *cum;
1896
1897 cum = get_cumulative_args (ca);
1898
1899 /* Under hard float abi, we better have argument entirely passed in
1900 registers or pushed on the stack so that we can reduce the complexity
1901 of dealing with cum->gpr_offset and cum->fpr_offset. */
1902 if (TARGET_HARD_FLOAT)
1903 return 0;
1904
1905 /* If we have already runned out of argument registers, return zero
1906 so that the argument will be entirely pushed on the stack. */
1907 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1908 >= NDS32_GPR_ARG_FIRST_REGNUM + NDS32_MAX_GPR_REGS_FOR_ARGS)
1909 return 0;
1910
1911 /* Calculate how many registers do we need for this argument. */
1912 needed_reg_count = NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1913
1914 /* Calculate how many argument registers have left for passing argument.
1915 Note that we should count it from next available register number. */
1916 remaining_reg_count
1917 = NDS32_MAX_GPR_REGS_FOR_ARGS
1918 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
8a498f99 1919 - NDS32_GPR_ARG_FIRST_REGNUM);
650fc469
CJW
1920
1921 /* Note that we have to return the nubmer of bytes, not registers count. */
1922 if (needed_reg_count > remaining_reg_count)
1923 return remaining_reg_count * UNITS_PER_WORD;
1924
1925 return 0;
1926}
1927
9304f876 1928static void
ef4bddc2 1929nds32_function_arg_advance (cumulative_args_t ca, machine_mode mode,
9304f876
CJW
1930 const_tree type, bool named)
1931{
1932 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1933
9304f876
CJW
1934 if (named)
1935 {
7f6cd86b 1936 /* We need to further check TYPE and MODE so that we can determine
e2286268 1937 which kind of register we shall advance. */
7f6cd86b
CJW
1938
1939 /* Under hard float abi, we may advance FPR registers. */
e2286268 1940 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
7f6cd86b 1941 {
e2286268
MC
1942 cum->fpr_offset
1943 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum->fpr_offset, mode, type)
1944 - NDS32_FPR_ARG_FIRST_REGNUM
1945 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
7f6cd86b
CJW
1946 }
1947 else
1948 {
1949 cum->gpr_offset
1950 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1951 - NDS32_GPR_ARG_FIRST_REGNUM
1952 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1953 }
1954 }
1955 else
1956 {
1957 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
8a498f99
CJW
1958 we can advance next register as well so that caller is
1959 able to pass arguments in registers and callee must be
1960 in charge of pushing all of them into stack. */
7f6cd86b
CJW
1961 if (!TARGET_HARD_FLOAT)
1962 {
1963 cum->gpr_offset
1964 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
1965 - NDS32_GPR_ARG_FIRST_REGNUM
1966 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1967 }
9304f876
CJW
1968 }
1969}
1970
1971static unsigned int
ef4bddc2 1972nds32_function_arg_boundary (machine_mode mode, const_tree type)
9304f876
CJW
1973{
1974 return (nds32_needs_double_word_align (mode, type)
1975 ? NDS32_DOUBLE_WORD_ALIGNMENT
1976 : PARM_BOUNDARY);
1977}
1978
1979/* -- How Scalar Function Values Are Returned. */
1980
1981static rtx
1982nds32_function_value (const_tree ret_type,
1983 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1984 bool outgoing ATTRIBUTE_UNUSED)
1985{
ef4bddc2 1986 machine_mode mode;
9304f876
CJW
1987 int unsignedp;
1988
1989 mode = TYPE_MODE (ret_type);
1990 unsignedp = TYPE_UNSIGNED (ret_type);
1991
e2286268
MC
1992 if (INTEGRAL_TYPE_P (ret_type))
1993 mode = promote_mode (ret_type, mode, &unsignedp);
9304f876 1994
e2286268
MC
1995 if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
1996 return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM);
1997 else
1998 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
9304f876
CJW
1999}
2000
2001static rtx
ef4bddc2 2002nds32_libcall_value (machine_mode mode,
9304f876
CJW
2003 const_rtx fun ATTRIBUTE_UNUSED)
2004{
e2286268
MC
2005 if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
2006 return gen_rtx_REG (mode, NDS32_FPR_RET_FIRST_REGNUM);
2007
9304f876
CJW
2008 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
2009}
2010
2011static bool
2012nds32_function_value_regno_p (const unsigned int regno)
2013{
e2286268
MC
2014 if (regno == NDS32_GPR_RET_FIRST_REGNUM
2015 || (TARGET_HARD_FLOAT
2016 && regno == NDS32_FPR_RET_FIRST_REGNUM))
2017 return true;
2018
2019 return false;
2020}
2021
2022/* -- How Large Values Are Returned. */
2023
2024static bool
2025nds32_return_in_memory (const_tree type,
2026 const_tree fntype ATTRIBUTE_UNUSED)
2027{
2028 /* Note that int_size_in_bytes can return -1 if the size can vary
2029 or is larger than an integer. */
2030 HOST_WIDE_INT size = int_size_in_bytes (type);
2031
2032 /* For COMPLEX_TYPE, if the total size cannot be hold within two registers,
2033 the return value is supposed to be in memory. We need to be aware of
2034 that the size may be -1. */
2035 if (TREE_CODE (type) == COMPLEX_TYPE)
2036 if (size < 0 || size > 2 * UNITS_PER_WORD)
2037 return true;
2038
2039 /* If it is BLKmode and the total size cannot be hold within two registers,
2040 the return value is supposed to be in memory. We need to be aware of
2041 that the size may be -1. */
2042 if (TYPE_MODE (type) == BLKmode)
2043 if (size < 0 || size > 2 * UNITS_PER_WORD)
2044 return true;
2045
2046 /* For other cases, having result in memory is unnecessary. */
2047 return false;
9304f876
CJW
2048}
2049
2050/* -- Function Entry and Exit. */
2051
2052/* The content produced from this function
2053 will be placed before prologue body. */
2054static void
42776416 2055nds32_asm_function_prologue (FILE *file)
9304f876
CJW
2056{
2057 int r;
2058 const char *func_name;
2059 tree attrs;
2060 tree name;
2061
2062 /* All stack frame information is supposed to be
2063 already computed when expanding prologue.
2064 The result is in cfun->machine.
2065 DO NOT call nds32_compute_stack_frame() here
2066 because it may corrupt the essential information. */
2067
2068 fprintf (file, "\t! BEGIN PROLOGUE\n");
2069 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
2070 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
2071 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
2072 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
2073
2074 /* Use df_regs_ever_live_p() to detect if the register
2075 is ever used in the current function. */
2076 fprintf (file, "\t! registers ever_live: ");
e2286268 2077 for (r = 0; r < 65; r++)
9304f876
CJW
2078 {
2079 if (df_regs_ever_live_p (r))
2080 fprintf (file, "%s, ", reg_names[r]);
2081 }
2082 fputc ('\n', file);
2083
2084 /* Display the attributes of this function. */
2085 fprintf (file, "\t! function attributes: ");
f2dafb91
CJW
2086 /* Get the attributes tree list.
2087 Note that GCC builds attributes list with reverse order. */
2088 attrs = DECL_ATTRIBUTES (current_function_decl);
9304f876
CJW
2089
2090 /* If there is no any attribute, print out "None". */
2091 if (!attrs)
2092 fprintf (file, "None");
2093
2094 /* If there are some attributes, try if we need to
2095 construct isr vector information. */
2096 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
2097 nds32_construct_isr_vectors_information (attrs, func_name);
2098
2099 /* Display all attributes of this function. */
2100 while (attrs)
2101 {
2102 name = TREE_PURPOSE (attrs);
2103 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
2104
2105 /* Pick up the next attribute. */
2106 attrs = TREE_CHAIN (attrs);
2107 }
2108 fputc ('\n', file);
2109}
2110
2111/* After rtl prologue has been expanded, this function is used. */
2112static void
2113nds32_asm_function_end_prologue (FILE *file)
2114{
2115 fprintf (file, "\t! END PROLOGUE\n");
2116
2117 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2118 we can generate special directive: ".omit_fp_begin"
2119 to guide linker doing fp-as-gp optimization.
2120 However, for a naked function, which means
2121 it should not have prologue/epilogue,
2122 using fp-as-gp still requires saving $fp by push/pop behavior and
2123 there is no benefit to use fp-as-gp on such small function.
2124 So we need to make sure this function is NOT naked as well. */
2125 if (!frame_pointer_needed
2126 && !cfun->machine->naked_p
2127 && cfun->machine->fp_as_gp_p)
2128 {
2129 fprintf (file, "\t! ----------------------------------------\n");
2130 fprintf (file, "\t! Guide linker to do "
2131 "link time optimization: fp-as-gp\n");
2132 fprintf (file, "\t! We add one more instruction to "
2133 "initialize $fp near to $gp location.\n");
2134 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
2135 fprintf (file, "\t! this extra instruction should be "
2136 "eliminated at link stage.\n");
2137 fprintf (file, "\t.omit_fp_begin\n");
2138 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
2139 fprintf (file, "\t! ----------------------------------------\n");
2140 }
2141}
2142
2143/* Before rtl epilogue has been expanded, this function is used. */
2144static void
2145nds32_asm_function_begin_epilogue (FILE *file)
2146{
2147 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2148 we can generate special directive: ".omit_fp_end"
2149 to claim fp-as-gp optimization range.
2150 However, for a naked function,
2151 which means it should not have prologue/epilogue,
2152 using fp-as-gp still requires saving $fp by push/pop behavior and
2153 there is no benefit to use fp-as-gp on such small function.
2154 So we need to make sure this function is NOT naked as well. */
2155 if (!frame_pointer_needed
2156 && !cfun->machine->naked_p
2157 && cfun->machine->fp_as_gp_p)
2158 {
2159 fprintf (file, "\t! ----------------------------------------\n");
2160 fprintf (file, "\t! Claim the range of fp-as-gp "
2161 "link time optimization\n");
2162 fprintf (file, "\t.omit_fp_end\n");
2163 fprintf (file, "\t! ----------------------------------------\n");
2164 }
2165
2166 fprintf (file, "\t! BEGIN EPILOGUE\n");
2167}
2168
2169/* The content produced from this function
2170 will be placed after epilogue body. */
2171static void
42776416 2172nds32_asm_function_epilogue (FILE *file)
9304f876
CJW
2173{
2174 fprintf (file, "\t! END EPILOGUE\n");
2175}
2176
2177static void
2178nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
2179 HOST_WIDE_INT delta,
2180 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
2181 tree function)
2182{
2183 int this_regno;
2184
2185 /* Make sure unwind info is emitted for the thunk if needed. */
2186 final_start_function (emit_barrier (), file, 1);
2187
2188 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
2189 ? 1
2190 : 0);
2191
2192 if (delta != 0)
2193 {
2194 if (satisfies_constraint_Is15 (GEN_INT (delta)))
2195 {
5af50159 2196 fprintf (file, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC "\n",
9304f876
CJW
2197 this_regno, this_regno, delta);
2198 }
2199 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
2200 {
5af50159 2201 fprintf (file, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC "\n", delta);
9304f876
CJW
2202 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2203 }
2204 else
2205 {
5af50159
KC
2206 fprintf (file,
2207 "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC ")\n",
2208 delta);
2209 fprintf (file,
2210 "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC ")\n",
2211 delta);
9304f876
CJW
2212 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
2213 }
2214 }
2215
2216 fprintf (file, "\tb\t");
2217 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
2218 fprintf (file, "\n");
2219
2220 final_end_function ();
2221}
2222
2223/* -- Permitting tail calls. */
2224
cc48a87f
CJW
2225/* Return true if it is ok to do sibling call optimization. */
2226static bool
2227nds32_function_ok_for_sibcall (tree decl,
2228 tree exp ATTRIBUTE_UNUSED)
2229{
2230 /* The DECL is NULL if it is an indirect call. */
2231
2232 /* 1. Do not apply sibling call if -mv3push is enabled,
2233 because pop25 instruction also represents return behavior.
2234 2. If this function is a variadic function, do not apply sibling call
2235 because the stack layout may be a mess.
2236 3. We don't want to apply sibling call optimization for indirect
2237 sibcall because the pop behavior in epilogue may pollute the
2238 content of caller-saved regsiter when the register is used for
2239 indirect sibcall. */
2240 return (!TARGET_V3PUSH
2241 && (cfun->machine->va_args_size == 0)
2242 && decl);
2243}
2244
9304f876
CJW
2245/* Determine whether we need to enable warning for function return check. */
2246static bool
2247nds32_warn_func_return (tree decl)
2248{
8a498f99
CJW
2249 /* Naked functions are implemented entirely in assembly, including the
2250 return sequence, so suppress warnings about this. */
9304f876
CJW
2251 return !nds32_naked_function_p (decl);
2252}
2253
2254\f
2255/* Implementing the Varargs Macros. */
2256
d4a6a4d9
CJW
2257static void
2258nds32_setup_incoming_varargs (cumulative_args_t ca,
ef4bddc2 2259 machine_mode mode,
d4a6a4d9
CJW
2260 tree type,
2261 int *pretend_args_size,
2262 int second_time ATTRIBUTE_UNUSED)
2263{
2264 unsigned int total_args_regs;
2265 unsigned int num_of_used_regs;
2266 unsigned int remaining_reg_count;
2267 CUMULATIVE_ARGS *cum;
2268
2269 /* If we are under hard float abi, we do not need to set *pretend_args_size.
2270 So that all nameless arguments are pushed by caller and all situation
2271 can be handled by GCC itself. */
2272 if (TARGET_HARD_FLOAT)
2273 return;
2274
2275 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
2276 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
2277 However, for nameless(anonymous) arguments, we should push them on the
2278 stack so that all the nameless arguments appear to have been passed
2279 consecutively in the memory for accessing. Hence, we need to check and
2280 exclude the registers that are used for named arguments. */
2281
2282 cum = get_cumulative_args (ca);
2283
2284 /* The MODE and TYPE describe the last argument.
2285 We need those information to determine the remaining registers
2286 for varargs. */
2287 total_args_regs
2288 = NDS32_MAX_GPR_REGS_FOR_ARGS + NDS32_GPR_ARG_FIRST_REGNUM;
2289 num_of_used_regs
2290 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum->gpr_offset, mode, type)
2291 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
2292
2293 remaining_reg_count = total_args_regs - num_of_used_regs;
2294 *pretend_args_size = remaining_reg_count * UNITS_PER_WORD;
2295
2296 return;
2297}
2298
9304f876
CJW
2299static bool
2300nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
2301{
d4a6a4d9
CJW
2302 /* If this hook returns true, the named argument of FUNCTION_ARG is always
2303 true for named arguments, and false for unnamed arguments. */
9304f876
CJW
2304 return true;
2305}
2306
2307\f
2308/* Trampolines for Nested Functions. */
2309
2310static void
2311nds32_asm_trampoline_template (FILE *f)
2312{
2313 if (TARGET_REDUCED_REGS)
2314 {
2315 /* Trampoline is not supported on reduced-set registers yet. */
2316 sorry ("a nested function is not supported for reduced registers");
2317 }
2318 else
2319 {
2320 asm_fprintf (f, "\t! Trampoline code template\n");
2321 asm_fprintf (f, "\t! This code fragment will be copied "
2322 "into stack on demand\n");
2323
2324 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
2325 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
2326 "! load nested function address\n");
2327 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
2328 "! load chain_value\n");
2329 asm_fprintf (f, "\tjr\t$r15\n");
2330 }
2331
2332 /* Preserve space ($pc + 16) for saving chain_value,
2333 nds32_trampoline_init will fill the value in this slot. */
2334 asm_fprintf (f, "\t! space for saving chain_value\n");
2335 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2336
2337 /* Preserve space ($pc + 20) for saving nested function address,
2338 nds32_trampoline_init will fill the value in this slot. */
2339 asm_fprintf (f, "\t! space for saving nested function address\n");
2340 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
2341}
2342
2343/* Emit RTL insns to initialize the variable parts of a trampoline. */
2344static void
2345nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2346{
2347 int i;
2348
2349 /* Nested function address. */
2350 rtx fnaddr;
2351 /* The memory rtx that is going to
2352 be filled with chain_value. */
2353 rtx chain_value_mem;
2354 /* The memory rtx that is going to
2355 be filled with nested function address. */
2356 rtx nested_func_mem;
2357
2358 /* Start address of trampoline code in stack, for doing cache sync. */
2359 rtx sync_cache_addr;
2360 /* Temporary register for sync instruction. */
2361 rtx tmp_reg;
2362 /* Instruction-cache sync instruction,
2363 requesting an argument as starting address. */
2364 rtx isync_insn;
2365 /* For convenience reason of doing comparison. */
2366 int tramp_align_in_bytes;
2367
2368 /* Trampoline is not supported on reduced-set registers yet. */
2369 if (TARGET_REDUCED_REGS)
2370 sorry ("a nested function is not supported for reduced registers");
2371
2372 /* STEP 1: Copy trampoline code template into stack,
8a498f99 2373 fill up essential data into stack. */
9304f876
CJW
2374
2375 /* Extract nested function address rtx. */
2376 fnaddr = XEXP (DECL_RTL (fndecl), 0);
2377
2378 /* m_tramp is memory rtx that is going to be filled with trampoline code.
2379 We have nds32_asm_trampoline_template() to emit template pattern. */
2380 emit_block_move (m_tramp, assemble_trampoline_template (),
2381 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2382
2383 /* After copying trampoline code into stack,
2384 fill chain_value into stack. */
2385 chain_value_mem = adjust_address (m_tramp, SImode, 16);
2386 emit_move_insn (chain_value_mem, chain_value);
2387 /* After copying trampoline code int stack,
2388 fill nested function address into stack. */
2389 nested_func_mem = adjust_address (m_tramp, SImode, 20);
2390 emit_move_insn (nested_func_mem, fnaddr);
2391
2392 /* STEP 2: Sync instruction-cache. */
2393
2394 /* We have successfully filled trampoline code into stack.
2395 However, in order to execute code in stack correctly,
2396 we must sync instruction cache. */
2397 sync_cache_addr = XEXP (m_tramp, 0);
2398 tmp_reg = gen_reg_rtx (SImode);
2399 isync_insn = gen_unspec_volatile_isync (tmp_reg);
2400
2401 /* Because nds32_cache_block_size is in bytes,
2402 we get trampoline alignment in bytes for convenient comparison. */
2403 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
2404
2405 if (tramp_align_in_bytes >= nds32_cache_block_size
2406 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
2407 {
2408 /* Under this condition, the starting address of trampoline
8a498f99
CJW
2409 must be aligned to the starting address of each cache block
2410 and we do not have to worry about cross-boundary issue. */
9304f876
CJW
2411 for (i = 0;
2412 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2413 / nds32_cache_block_size;
2414 i++)
2415 {
2416 emit_move_insn (tmp_reg,
2417 plus_constant (Pmode, sync_cache_addr,
2418 nds32_cache_block_size * i));
2419 emit_insn (isync_insn);
2420 }
2421 }
2422 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
2423 {
2424 /* The starting address of trampoline code
8a498f99
CJW
2425 may not be aligned to the cache block,
2426 so the trampoline code may be across two cache block.
2427 We need to sync the last element, which is 4-byte size,
2428 of trampoline template. */
9304f876
CJW
2429 for (i = 0;
2430 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
2431 / nds32_cache_block_size;
2432 i++)
2433 {
2434 emit_move_insn (tmp_reg,
2435 plus_constant (Pmode, sync_cache_addr,
2436 nds32_cache_block_size * i));
2437 emit_insn (isync_insn);
2438 }
2439
2440 /* The last element of trampoline template is 4-byte size. */
2441 emit_move_insn (tmp_reg,
2442 plus_constant (Pmode, sync_cache_addr,
2443 TRAMPOLINE_SIZE - 4));
2444 emit_insn (isync_insn);
2445 }
2446 else
2447 {
2448 /* This is the simplest case.
8a498f99
CJW
2449 Because TRAMPOLINE_SIZE is less than or
2450 equal to nds32_cache_block_size,
2451 we can just sync start address and
2452 the last element of trampoline code. */
9304f876
CJW
2453
2454 /* Sync starting address of tampoline code. */
2455 emit_move_insn (tmp_reg, sync_cache_addr);
2456 emit_insn (isync_insn);
2457 /* Sync the last element, which is 4-byte size,
8a498f99 2458 of trampoline template. */
9304f876
CJW
2459 emit_move_insn (tmp_reg,
2460 plus_constant (Pmode, sync_cache_addr,
2461 TRAMPOLINE_SIZE - 4));
2462 emit_insn (isync_insn);
2463 }
2464
2465 /* Set instruction serialization barrier
2466 to guarantee the correct operations. */
2467 emit_insn (gen_unspec_volatile_isb ());
2468}
2469
2470\f
2471/* Addressing Modes. */
2472
2473static bool
ef4bddc2 2474nds32_legitimate_address_p (machine_mode mode, rtx x, bool strict)
9304f876 2475{
e2286268
MC
2476 if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
2477 {
2478 /* When using floating-point instructions,
2479 we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */
2480 if ((mode == DFmode || mode == SFmode)
2481 && (GET_CODE (x) == SYMBOL_REF
2482 || GET_CODE(x) == CONST))
2483 return false;
2484
2485 /* Allow [post_modify] addressing mode, when using FPU instructions. */
2486 if (GET_CODE (x) == POST_MODIFY
2487 && mode == DFmode)
2488 {
2489 if (GET_CODE (XEXP (x, 0)) == REG
2490 && GET_CODE (XEXP (x, 1)) == PLUS)
2491 {
2492 rtx plus_op = XEXP (x, 1);
2493 rtx op0 = XEXP (plus_op, 0);
2494 rtx op1 = XEXP (plus_op, 1);
2495
2496 if (nds32_address_register_rtx_p (op0, strict)
2497 && CONST_INT_P (op1))
2498 {
2499 if (satisfies_constraint_Is14 (op1))
2500 {
5f2a98c3
CJW
2501 /* If it is not under strictly aligned situation,
2502 we can return true without checking alignment. */
2503 if (!cfun->machine->strict_aligned_p)
2504 return true;
e2286268
MC
2505 /* Make sure address is word alignment.
2506 Currently we do not have 64-bit load/store yet,
2507 so we will use two 32-bit load/store instructions to do
2508 memory access and they are single word alignment. */
5f2a98c3 2509 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1)))
e2286268
MC
2510 return true;
2511 }
2512 }
2513 }
2514 }
2515 }
2516
9304f876
CJW
2517 /* For (mem:DI addr) or (mem:DF addr) case,
2518 we only allow 'addr' to be [reg], [symbol_ref],
8a498f99 2519 [const], or [reg + const_int] pattern. */
9304f876
CJW
2520 if (mode == DImode || mode == DFmode)
2521 {
2522 /* Allow [Reg + const_int] addressing mode. */
2523 if (GET_CODE (x) == PLUS)
2524 {
2525 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2526 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
2527 && CONST_INT_P (XEXP (x, 1)))
2528 return true;
9304f876
CJW
2529 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2530 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
2531 && CONST_INT_P (XEXP (x, 0)))
2532 return true;
2533 }
2534
e2286268
MC
2535 /* Allow [post_inc] and [post_dec] addressing mode. */
2536 if (GET_CODE (x) == POST_INC || GET_CODE (x) == POST_DEC)
2537 {
2538 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2539 return true;
2540 }
2541
9304f876
CJW
2542 /* Now check [reg], [symbol_ref], and [const]. */
2543 if (GET_CODE (x) != REG
2544 && GET_CODE (x) != SYMBOL_REF
2545 && GET_CODE (x) != CONST)
2546 return false;
2547 }
2548
2549 /* Check if 'x' is a valid address. */
2550 switch (GET_CODE (x))
2551 {
2552 case REG:
2553 /* (mem (reg A)) => [Ra] */
2554 return nds32_address_register_rtx_p (x, strict);
2555
2556 case SYMBOL_REF:
4855be84
CJW
2557 /* (mem (symbol_ref A)) => [symbol_ref] */
2558 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
8a498f99 2559 during or after LRA/reload phase. */
4855be84 2560 if (TARGET_CMODEL_LARGE
9304f876
CJW
2561 && (reload_completed
2562 || reload_in_progress
2563 || lra_in_progress))
2564 return false;
4855be84 2565 /* If -mcmodel=medium and the symbol references to rodata section,
8a498f99
CJW
2566 the 'symbol_ref' is not a valid address during or after
2567 LRA/reload phase. */
4855be84
CJW
2568 if (TARGET_CMODEL_MEDIUM
2569 && NDS32_SYMBOL_REF_RODATA_P (x)
9304f876
CJW
2570 && (reload_completed
2571 || reload_in_progress
2572 || lra_in_progress))
2573 return false;
2574
4855be84
CJW
2575 return true;
2576
2577 case CONST:
9304f876 2578 /* (mem (const (...)))
8a498f99 2579 => [ + const_addr ], where const_addr = symbol_ref + const_int */
9304f876
CJW
2580 if (GET_CODE (XEXP (x, 0)) == PLUS)
2581 {
2582 rtx plus_op = XEXP (x, 0);
2583
2584 rtx op0 = XEXP (plus_op, 0);
2585 rtx op1 = XEXP (plus_op, 1);
2586
2587 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
4855be84
CJW
2588 {
2589 /* Now we see the [ + const_addr ] pattern, but we need
8a498f99 2590 some further checking. */
4855be84 2591 /* If -mcmodel=large, the 'const_addr' is not a valid address
8a498f99 2592 during or after LRA/reload phase. */
4855be84
CJW
2593 if (TARGET_CMODEL_LARGE
2594 && (reload_completed
2595 || reload_in_progress
2596 || lra_in_progress))
2597 return false;
2598 /* If -mcmodel=medium and the symbol references to rodata section,
8a498f99
CJW
2599 the 'const_addr' is not a valid address during or after
2600 LRA/reload phase. */
4855be84
CJW
2601 if (TARGET_CMODEL_MEDIUM
2602 && NDS32_SYMBOL_REF_RODATA_P (op0)
2603 && (reload_completed
2604 || reload_in_progress
2605 || lra_in_progress))
2606 return false;
2607
2608 /* At this point we can make sure 'const_addr' is a
2609 valid address. */
2610 return true;
2611 }
9304f876
CJW
2612 }
2613
2614 return false;
2615
2616 case POST_MODIFY:
2617 /* (mem (post_modify (reg) (plus (reg) (reg))))
8a498f99 2618 => [Ra], Rb */
9304f876 2619 /* (mem (post_modify (reg) (plus (reg) (const_int))))
8a498f99 2620 => [Ra], const_int */
9304f876
CJW
2621 if (GET_CODE (XEXP (x, 0)) == REG
2622 && GET_CODE (XEXP (x, 1)) == PLUS)
2623 {
2624 rtx plus_op = XEXP (x, 1);
2625
2626 rtx op0 = XEXP (plus_op, 0);
2627 rtx op1 = XEXP (plus_op, 1);
2628
2629 if (nds32_address_register_rtx_p (op0, strict)
2630 && nds32_legitimate_index_p (mode, op1, strict))
2631 return true;
2632 else
2633 return false;
2634 }
2635
2636 return false;
2637
2638 case POST_INC:
2639 case POST_DEC:
2640 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2641 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2642 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
8a498f99 2643 We only need to deal with register Ra. */
9304f876
CJW
2644 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
2645 return true;
2646 else
2647 return false;
2648
2649 case PLUS:
2650 /* (mem (plus reg const_int))
8a498f99 2651 => [Ra + imm] */
9304f876 2652 /* (mem (plus reg reg))
8a498f99 2653 => [Ra + Rb] */
9304f876 2654 /* (mem (plus (mult reg const_int) reg))
8a498f99 2655 => [Ra + Rb << sv] */
9304f876
CJW
2656 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
2657 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
2658 return true;
2659 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
2660 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
2661 return true;
2662 else
2663 return false;
2664
2665 case LO_SUM:
34425025
CJW
2666 /* (mem (lo_sum (reg) (symbol_ref))) */
2667 /* (mem (lo_sum (reg) (const))) */
2668 gcc_assert (REG_P (XEXP (x, 0)));
2669 if (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
2670 || GET_CODE (XEXP (x, 1)) == CONST)
2671 return nds32_legitimate_address_p (mode, XEXP (x, 1), strict);
2672 else
2673 return false;
9304f876
CJW
2674
2675 default:
2676 return false;
2677 }
2678}
2679
5b6f2bf3
CJW
2680\f
2681/* Condition Code Status. */
2682
2683/* -- Representation of condition codes using registers. */
2684
2685static void
2686nds32_canonicalize_comparison (int *code,
2687 rtx *op0 ATTRIBUTE_UNUSED,
2688 rtx *op1,
2689 bool op0_preserve_value ATTRIBUTE_UNUSED)
2690{
2691 /* When the instruction combination pass tries to combine a comparison insn
2692 with its previous insns, it also transforms the operator in order to
2693 minimize its constant field. For example, it tries to transform a
2694 comparison insn from
2695 (set (reg:SI 54)
2696 (ltu:SI (reg:SI 52)
2697 (const_int 10 [0xa])))
2698 to
2699 (set (reg:SI 54)
2700 (leu:SI (reg:SI 52)
2701 (const_int 9 [0x9])))
2702
2703 However, the nds32 target only provides instructions supporting the LTU
2704 operation directly, and the implementation of the pattern "cbranchsi4"
2705 only expands the LTU form. In order to handle the non-LTU operations
2706 generated from passes other than the RTL expansion pass, we have to
2707 implement this hook to revert those changes. Since we only expand the LTU
2708 operator in the RTL expansion pass, we might only need to handle the LEU
2709 case, unless we find other optimization passes perform more aggressive
2710 transformations. */
2711
2712 if (*code == LEU && CONST_INT_P (*op1))
2713 {
2714 *op1 = gen_int_mode (INTVAL (*op1) + 1, SImode);
2715 *code = LTU;
2716 }
2717}
2718
9304f876
CJW
2719\f
2720/* Describing Relative Costs of Operations. */
2721
19ac960a 2722static int
ef4bddc2 2723nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
19ac960a
CJW
2724 reg_class_t from,
2725 reg_class_t to)
9304f876 2726{
e2286268
MC
2727 if ((from == FP_REGS && to != FP_REGS)
2728 || (from != FP_REGS && to == FP_REGS))
2729 return 9;
2730 else if (from == HIGH_REGS || to == HIGH_REGS)
2731 return optimize_size ? 6 : 2;
2732 else
2733 return 2;
9304f876
CJW
2734}
2735
19ac960a 2736static int
ef4bddc2 2737nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
19ac960a
CJW
2738 reg_class_t rclass ATTRIBUTE_UNUSED,
2739 bool in ATTRIBUTE_UNUSED)
9304f876
CJW
2740{
2741 return 8;
2742}
2743
2744/* This target hook describes the relative costs of RTL expressions.
2745 Return 'true' when all subexpressions of x have been processed.
2746 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2747 Refer to gcc/rtlanal.c for more information. */
2748static bool
2749nds32_rtx_costs (rtx x,
e548c9df 2750 machine_mode mode,
9304f876 2751 int outer_code,
89a4b547 2752 int opno,
9304f876
CJW
2753 int *total,
2754 bool speed)
2755{
e548c9df 2756 return nds32_rtx_costs_impl (x, mode, outer_code, opno, total, speed);
9304f876
CJW
2757}
2758
19ac960a
CJW
2759static int
2760nds32_address_cost (rtx address,
ef4bddc2 2761 machine_mode mode,
19ac960a
CJW
2762 addr_space_t as,
2763 bool speed)
9304f876 2764{
89a4b547 2765 return nds32_address_cost_impl (address, mode, as, speed);
9304f876
CJW
2766}
2767
511a41d7
CJW
2768\f
2769/* Dividing the Output into Sections (Texts, Data, . . . ). */
2770
2771/* If references to a symbol or a constant must be treated differently
2772 depending on something about the variable or function named by the symbol
2773 (such as what section it is in), we use this hook to store flags
2774 in symbol_ref rtx. */
2775static void
2776nds32_encode_section_info (tree decl, rtx rtl, int new_decl_p)
2777{
2778 default_encode_section_info (decl, rtl, new_decl_p);
2779
2780 /* For the memory rtx, if it references to rodata section, we can store
2781 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
2782 nds32_legitimate_address_p() can determine how to treat such symbol_ref
2783 based on -mcmodel=X and this information. */
2784 if (MEM_P (rtl) && MEM_READONLY_P (rtl))
2785 {
2786 rtx addr = XEXP (rtl, 0);
2787
2788 if (GET_CODE (addr) == SYMBOL_REF)
2789 {
2790 /* For (mem (symbol_ref X)) case. */
2791 SYMBOL_REF_FLAGS (addr) |= NDS32_SYMBOL_FLAG_RODATA;
2792 }
2793 else if (GET_CODE (addr) == CONST
2794 && GET_CODE (XEXP (addr, 0)) == PLUS)
2795 {
2796 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
2797 rtx plus_op = XEXP (addr, 0);
2798 rtx op0 = XEXP (plus_op, 0);
2799 rtx op1 = XEXP (plus_op, 1);
2800
2801 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
2802 SYMBOL_REF_FLAGS (op0) |= NDS32_SYMBOL_FLAG_RODATA;
2803 }
2804 }
2805}
2806
9304f876
CJW
2807\f
2808/* Defining the Output Assembler Language. */
2809
2810/* -- The Overall Framework of an Assembler File. */
2811
2812static void
2813nds32_asm_file_start (void)
2814{
9304f876
CJW
2815 default_file_start ();
2816
2817 /* Tell assembler which ABI we are using. */
2818 fprintf (asm_out_file, "\t! ABI version\n");
e2286268
MC
2819 if (TARGET_HARD_FLOAT)
2820 fprintf (asm_out_file, "\t.abi_2fp_plus\n");
2821 else
2822 fprintf (asm_out_file, "\t.abi_2\n");
9304f876
CJW
2823
2824 /* Tell assembler that this asm code is generated by compiler. */
2825 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
2826 fprintf (asm_out_file, "\t.flag\tverbatim\n");
2827 /* Give assembler the size of each vector for interrupt handler. */
2828 fprintf (asm_out_file, "\t! This vector size directive is required "
2829 "for checking inconsistency on interrupt handler\n");
2830 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
2831
9304f876
CJW
2832 fprintf (asm_out_file, "\t! ------------------------------------\n");
2833
2834 if (TARGET_ISA_V2)
2835 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
2836 if (TARGET_ISA_V3)
2837 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
2838 if (TARGET_ISA_V3M)
2839 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
2840
77b7a1ca
CJW
2841 if (TARGET_CMODEL_SMALL)
2842 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "SMALL");
2843 if (TARGET_CMODEL_MEDIUM)
2844 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "MEDIUM");
2845 if (TARGET_CMODEL_LARGE)
2846 fprintf (asm_out_file, "\t! Code model\t\t: %s\n", "LARGE");
2847
9304f876
CJW
2848 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
2849 ((TARGET_BIG_ENDIAN) ? "big-endian"
2850 : "little-endian"));
e2286268
MC
2851 fprintf (asm_out_file, "\t! Use SP floating-point instruction\t: %s\n",
2852 ((TARGET_FPU_SINGLE) ? "Yes"
2853 : "No"));
2854 fprintf (asm_out_file, "\t! Use DP floating-point instruction\t: %s\n",
2855 ((TARGET_FPU_DOUBLE) ? "Yes"
2856 : "No"));
2857 fprintf (asm_out_file, "\t! ABI version\t\t: %s\n",
2858 ((TARGET_HARD_FLOAT) ? "ABI2FP+"
2859 : "ABI2"));
9304f876
CJW
2860
2861 fprintf (asm_out_file, "\t! ------------------------------------\n");
2862
2863 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
2864 ((TARGET_CMOV) ? "Yes"
2865 : "No"));
2866 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
aa4b851c 2867 ((TARGET_EXT_PERF) ? "Yes"
9304f876 2868 : "No"));
aa4b851c
CJW
2869 fprintf (asm_out_file, "\t! Use performance extension 2\t: %s\n",
2870 ((TARGET_EXT_PERF2) ? "Yes"
2871 : "No"));
2872 fprintf (asm_out_file, "\t! Use string extension\t\t: %s\n",
2873 ((TARGET_EXT_STRING) ? "Yes"
2874 : "No"));
9304f876
CJW
2875
2876 fprintf (asm_out_file, "\t! ------------------------------------\n");
2877
2878 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
2879 ((TARGET_V3PUSH) ? "Yes"
2880 : "No"));
2881 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
2882 ((TARGET_16_BIT) ? "Yes"
2883 : "No"));
9304f876
CJW
2884 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
2885 ((TARGET_REDUCED_REGS) ? "Yes"
2886 : "No"));
2887
bc8a8810
MC
2888 fprintf (asm_out_file, "\t! Support unaligned access\t\t: %s\n",
2889 (flag_unaligned_access ? "Yes"
2890 : "No"));
2891
9304f876
CJW
2892 fprintf (asm_out_file, "\t! ------------------------------------\n");
2893
2894 if (optimize_size)
2895 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
10c8bd03
CJW
2896 else if (optimize_fast)
2897 fprintf (asm_out_file, "\t! Optimization level\t: -Ofast\n");
2898 else if (optimize_debug)
2899 fprintf (asm_out_file, "\t! Optimization level\t: -Og\n");
9304f876
CJW
2900 else
2901 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
2902
2903 fprintf (asm_out_file, "\t! ------------------------------------\n");
2904
2905 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
2906 nds32_cache_block_size);
2907
2908 fprintf (asm_out_file, "\t! ------------------------------------\n");
2909
c23a919b 2910 nds32_asm_file_start_for_isr ();
9304f876
CJW
2911}
2912
2913static void
2914nds32_asm_file_end (void)
2915{
c23a919b 2916 nds32_asm_file_end_for_isr ();
9304f876
CJW
2917
2918 fprintf (asm_out_file, "\t! ------------------------------------\n");
2919}
2920
2921/* -- Output and Generation of Labels. */
2922
2923static void
2924nds32_asm_globalize_label (FILE *stream, const char *name)
2925{
2926 fputs ("\t.global\t", stream);
2927 assemble_name (stream, name);
2928 fputs ("\n", stream);
2929}
2930
2931/* -- Output of Assembler Instructions. */
2932
2933static void
2934nds32_print_operand (FILE *stream, rtx x, int code)
2935{
a3b13564
KC
2936 HOST_WIDE_INT one_position;
2937 HOST_WIDE_INT zero_position;
e2286268
MC
2938 bool pick_lsb_p = false;
2939 bool pick_msb_p = false;
2940 int regno;
2941
9304f876
CJW
2942 int op_value;
2943
2944 switch (code)
2945 {
2946 case 0 :
2947 /* Do nothing special. */
2948 break;
2949
a3b13564
KC
2950 case 'b':
2951 /* Use exact_log2() to search the 0-bit position. */
2952 gcc_assert (CONST_INT_P (x));
2953 zero_position = exact_log2 (~UINTVAL (x) & GET_MODE_MASK (SImode));
2954 gcc_assert (zero_position != -1);
2955 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, zero_position);
2956
2957 /* No need to handle following process, so return immediately. */
2958 return;
2959
8656bbcf
SC
2960 case 'e':
2961 gcc_assert (MEM_P (x)
2962 && GET_CODE (XEXP (x, 0)) == PLUS
2963 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
2964 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (XEXP (x, 0), 1)));
2965
2966 /* No need to handle following process, so return immediately. */
2967 return;
a3b13564
KC
2968 case 'B':
2969 /* Use exact_log2() to search the 1-bit position. */
2970 gcc_assert (CONST_INT_P (x));
2971 one_position = exact_log2 (UINTVAL (x) & GET_MODE_MASK (SImode));
2972 gcc_assert (one_position != -1);
2973 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, one_position);
2974
2975 /* No need to handle following process, so return immediately. */
2976 return;
2977
e2286268
MC
2978 case 'L':
2979 /* X is supposed to be REG rtx. */
2980 gcc_assert (REG_P (x));
2981 /* Claim that we are going to pick LSB part of X. */
2982 pick_lsb_p = true;
2983 break;
2984
2985 case 'H':
2986 /* X is supposed to be REG rtx. */
2987 gcc_assert (REG_P (x));
2988 /* Claim that we are going to pick MSB part of X. */
2989 pick_msb_p = true;
2990 break;
2991
9304f876
CJW
2992 case 'V':
2993 /* 'x' is supposed to be CONST_INT, get the value. */
2994 gcc_assert (CONST_INT_P (x));
2995 op_value = INTVAL (x);
2996
2997 /* According to the Andes architecture,
8a498f99
CJW
2998 the system/user register index range is 0 ~ 1023.
2999 In order to avoid conflict between user-specified-integer value
3000 and enum-specified-register value,
3001 the 'enum nds32_intrinsic_registers' value
3002 in nds32_intrinsic.h starts from 1024. */
9304f876
CJW
3003 if (op_value < 1024 && op_value >= 0)
3004 {
3005 /* If user gives integer value directly (0~1023),
3006 we just print out the value. */
5af50159 3007 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, op_value);
9304f876
CJW
3008 }
3009 else if (op_value < 0
3010 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
3011 + 1024))
3012 {
3013 /* The enum index value for array size is out of range. */
3014 error ("intrinsic register index is out of range");
3015 }
3016 else
3017 {
3018 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3019 we can print out register name. Remember to substract 1024. */
3020 fprintf (stream, "%s",
3021 nds32_intrinsic_register_names[op_value - 1024]);
3022 }
3023
3024 /* No need to handle following process, so return immediately. */
3025 return;
3026
f1a0afe2
MC
3027 case 'R': /* cctl valck */
3028 /* Note the cctl divide to 5 group and share the same name table. */
3029 if (op_value < 0 || op_value > 4)
3030 error ("CCTL intrinsic function subtype out of range!");
3031 fprintf (stream, "%s", nds32_cctl_names[op_value]);
3032 return;
3033
3034 case 'T': /* cctl idxwbinv */
3035 /* Note the cctl divide to 5 group and share the same name table. */
3036 if (op_value < 0 || op_value > 4)
3037 error ("CCTL intrinsic function subtype out of range!");
3038 fprintf (stream, "%s", nds32_cctl_names[op_value + 4]);
3039 return;
3040
3041 case 'U': /* cctl vawbinv */
3042 /* Note the cctl divide to 5 group and share the same name table. */
3043 if (op_value < 0 || op_value > 4)
3044 error ("CCTL intrinsic function subtype out of range!");
3045 fprintf (stream, "%s", nds32_cctl_names[op_value + 8]);
3046 return;
3047
3048 case 'X': /* cctl idxread */
3049 /* Note the cctl divide to 5 group and share the same name table. */
3050 if (op_value < 0 || op_value > 4)
3051 error ("CCTL intrinsic function subtype out of range!");
3052 fprintf (stream, "%s", nds32_cctl_names[op_value + 12]);
3053 return;
3054
3055 case 'W': /* cctl idxwitre */
3056 /* Note the cctl divide to 5 group and share the same name table. */
3057 if (op_value < 0 || op_value > 4)
3058 error ("CCTL intrinsic function subtype out of range!");
3059 fprintf (stream, "%s", nds32_cctl_names[op_value + 16]);
3060 return;
3061
57aaf0cc
MC
3062 case 'Z': /* dpref */
3063 fprintf (stream, "%s", nds32_dpref_names[op_value]);
3064 return;
3065
9304f876
CJW
3066 default :
3067 /* Unknown flag. */
3068 output_operand_lossage ("invalid operand output code");
3069 break;
3070 }
3071
3072 switch (GET_CODE (x))
3073 {
3074 case LABEL_REF:
3075 case SYMBOL_REF:
3076 output_addr_const (stream, x);
3077 break;
3078
3079 case REG:
e2286268
MC
3080 /* Print a Double-precision register name. */
3081 if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
3082 && NDS32_IS_FPR_REGNUM (REGNO (x)))
3083 {
3084 regno = REGNO (x);
3085 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno))
3086 {
3087 output_operand_lossage ("invalid operand for code '%c'", code);
3088 break;
3089 }
3090 fprintf (stream, "$fd%d", (regno - NDS32_FIRST_FPR_REGNUM) >> 1);
3091 break;
3092 }
3093
3094 /* Print LSB or MSB part of register pair if the
3095 constraint modifier 'L' or 'H' is specified. */
3096 if ((GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
3097 && NDS32_IS_GPR_REGNUM (REGNO (x)))
3098 {
3099 if ((pick_lsb_p && WORDS_BIG_ENDIAN)
3100 || (pick_msb_p && !WORDS_BIG_ENDIAN))
3101 {
3102 /* If we would like to print out LSB register under big-endian,
3103 or print out MSB register under little-endian, we need to
3104 increase register number. */
3105 regno = REGNO (x);
3106 regno++;
3107 fputs (reg_names[regno], stream);
3108 break;
3109 }
3110 }
3111
9304f876 3112 /* Forbid using static chain register ($r16)
8a498f99 3113 on reduced-set registers configuration. */
9304f876
CJW
3114 if (TARGET_REDUCED_REGS
3115 && REGNO (x) == STATIC_CHAIN_REGNUM)
3116 sorry ("a nested function is not supported for reduced registers");
3117
3118 /* Normal cases, print out register name. */
3119 fputs (reg_names[REGNO (x)], stream);
3120 break;
3121
3122 case MEM:
cc8ca59e 3123 output_address (GET_MODE (x), XEXP (x, 0));
9304f876
CJW
3124 break;
3125
e2286268
MC
3126 case HIGH:
3127 if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE)
3128 {
3129 const REAL_VALUE_TYPE *rv;
3130 long val;
3131 gcc_assert (GET_MODE (x) == SFmode);
3132
3133 rv = CONST_DOUBLE_REAL_VALUE (XEXP (x, 0));
3134 REAL_VALUE_TO_TARGET_SINGLE (*rv, val);
3135
3136 fprintf (stream, "hi20(0x%lx)", val);
3137 }
3138 else
3139 gcc_unreachable ();
3140 break;
3141
3142 case CONST_DOUBLE:
3143 const REAL_VALUE_TYPE *rv;
3144 long val;
3145 gcc_assert (GET_MODE (x) == SFmode);
3146
3147 rv = CONST_DOUBLE_REAL_VALUE (x);
3148 REAL_VALUE_TO_TARGET_SINGLE (*rv, val);
3149
3150 fprintf (stream, "0x%lx", val);
3151 break;
3152
9304f876
CJW
3153 case CODE_LABEL:
3154 case CONST_INT:
3155 case CONST:
3156 output_addr_const (stream, x);
3157 break;
3158
3159 default:
3160 /* Generally, output_addr_const () is able to handle most cases.
8a498f99
CJW
3161 We want to see what CODE could appear,
3162 so we use gcc_unreachable() to stop it. */
9304f876
CJW
3163 debug_rtx (x);
3164 gcc_unreachable ();
3165 break;
3166 }
3167}
3168
3169static void
cc8ca59e 3170nds32_print_operand_address (FILE *stream, machine_mode /*mode*/, rtx x)
9304f876
CJW
3171{
3172 rtx op0, op1;
3173
3174 switch (GET_CODE (x))
3175 {
3176 case SYMBOL_REF:
3177 case CONST:
3178 /* [ + symbol_ref] */
3179 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3180 fputs ("[ + ", stream);
3181 output_addr_const (stream, x);
3182 fputs ("]", stream);
3183 break;
3184
3185 case REG:
3186 /* Forbid using static chain register ($r16)
8a498f99 3187 on reduced-set registers configuration. */
9304f876
CJW
3188 if (TARGET_REDUCED_REGS
3189 && REGNO (x) == STATIC_CHAIN_REGNUM)
3190 sorry ("a nested function is not supported for reduced registers");
3191
3192 /* [Ra] */
3193 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
3194 break;
3195
3196 case PLUS:
3197 op0 = XEXP (x, 0);
3198 op1 = XEXP (x, 1);
3199
3200 /* Checking op0, forbid using static chain register ($r16)
8a498f99 3201 on reduced-set registers configuration. */
9304f876
CJW
3202 if (TARGET_REDUCED_REGS
3203 && REG_P (op0)
3204 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3205 sorry ("a nested function is not supported for reduced registers");
3206 /* Checking op1, forbid using static chain register ($r16)
8a498f99 3207 on reduced-set registers configuration. */
9304f876
CJW
3208 if (TARGET_REDUCED_REGS
3209 && REG_P (op1)
3210 && REGNO (op1) == STATIC_CHAIN_REGNUM)
3211 sorry ("a nested function is not supported for reduced registers");
3212
3213 if (REG_P (op0) && CONST_INT_P (op1))
3214 {
3215 /* [Ra + imm] */
5af50159
KC
3216 fprintf (stream, "[%s + (" HOST_WIDE_INT_PRINT_DEC ")]",
3217 reg_names[REGNO (op0)], INTVAL (op1));
9304f876
CJW
3218 }
3219 else if (REG_P (op0) && REG_P (op1))
3220 {
3221 /* [Ra + Rb] */
3222 fprintf (stream, "[%s + %s]",
3223 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
3224 }
3225 else if (GET_CODE (op0) == MULT && REG_P (op1))
3226 {
3227 /* [Ra + Rb << sv]
3228 From observation, the pattern looks like:
3229 (plus:SI (mult:SI (reg:SI 58)
8a498f99
CJW
3230 (const_int 4 [0x4]))
3231 (reg/f:SI 57)) */
9304f876
CJW
3232 int sv;
3233
3234 /* We need to set sv to output shift value. */
3235 if (INTVAL (XEXP (op0, 1)) == 1)
3236 sv = 0;
3237 else if (INTVAL (XEXP (op0, 1)) == 2)
3238 sv = 1;
3239 else if (INTVAL (XEXP (op0, 1)) == 4)
3240 sv = 2;
f62a2af5
CJW
3241 else if (INTVAL (XEXP (op0, 1)) == 8)
3242 sv = 3;
9304f876
CJW
3243 else
3244 gcc_unreachable ();
3245
3246 fprintf (stream, "[%s + %s << %d]",
3247 reg_names[REGNO (op1)],
3248 reg_names[REGNO (XEXP (op0, 0))],
3249 sv);
3250 }
3251 else
3252 {
3253 /* The control flow is not supposed to be here. */
3254 debug_rtx (x);
3255 gcc_unreachable ();
3256 }
3257
3258 break;
3259
3260 case POST_MODIFY:
3261 /* (post_modify (regA) (plus (regA) (regB)))
8a498f99
CJW
3262 (post_modify (regA) (plus (regA) (const_int)))
3263 We would like to extract
3264 regA and regB (or const_int) from plus rtx. */
9304f876
CJW
3265 op0 = XEXP (XEXP (x, 1), 0);
3266 op1 = XEXP (XEXP (x, 1), 1);
3267
3268 /* Checking op0, forbid using static chain register ($r16)
8a498f99 3269 on reduced-set registers configuration. */
9304f876
CJW
3270 if (TARGET_REDUCED_REGS
3271 && REG_P (op0)
3272 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3273 sorry ("a nested function is not supported for reduced registers");
3274 /* Checking op1, forbid using static chain register ($r16)
8a498f99 3275 on reduced-set registers configuration. */
9304f876
CJW
3276 if (TARGET_REDUCED_REGS
3277 && REG_P (op1)
3278 && REGNO (op1) == STATIC_CHAIN_REGNUM)
3279 sorry ("a nested function is not supported for reduced registers");
3280
3281 if (REG_P (op0) && REG_P (op1))
3282 {
3283 /* [Ra], Rb */
3284 fprintf (stream, "[%s], %s",
3285 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
3286 }
3287 else if (REG_P (op0) && CONST_INT_P (op1))
3288 {
3289 /* [Ra], imm */
5af50159
KC
3290 fprintf (stream, "[%s], " HOST_WIDE_INT_PRINT_DEC,
3291 reg_names[REGNO (op0)], INTVAL (op1));
9304f876
CJW
3292 }
3293 else
3294 {
3295 /* The control flow is not supposed to be here. */
3296 debug_rtx (x);
3297 gcc_unreachable ();
3298 }
3299
3300 break;
3301
3302 case POST_INC:
3303 case POST_DEC:
3304 op0 = XEXP (x, 0);
3305
3306 /* Checking op0, forbid using static chain register ($r16)
8a498f99 3307 on reduced-set registers configuration. */
9304f876
CJW
3308 if (TARGET_REDUCED_REGS
3309 && REG_P (op0)
3310 && REGNO (op0) == STATIC_CHAIN_REGNUM)
3311 sorry ("a nested function is not supported for reduced registers");
3312
3313 if (REG_P (op0))
3314 {
3315 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3316 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3317 We only need to deal with register Ra. */
3318 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
3319 }
3320 else
3321 {
3322 /* The control flow is not supposed to be here. */
3323 debug_rtx (x);
3324 gcc_unreachable ();
3325 }
3326
3327 break;
3328
3329 default :
3330 /* Generally, output_addr_const () is able to handle most cases.
8a498f99
CJW
3331 We want to see what CODE could appear,
3332 so we use gcc_unreachable() to stop it. */
9304f876
CJW
3333 debug_rtx (x);
3334 gcc_unreachable ();
3335 break;
3336 }
3337}
3338
e2286268
MC
3339/* -- Assembler Commands for Exception Regions. */
3340
3341static rtx
3342nds32_dwarf_register_span (rtx reg)
3343{
3344 rtx dwarf_high, dwarf_low;
3345 rtx dwarf_single;
3346 machine_mode mode;
3347 int regno;
3348
3349 mode = GET_MODE (reg);
3350 regno = REGNO (reg);
3351
3352 /* We need to adjust dwarf register information for floating-point registers
3353 rather than using default register number mapping. */
3354 if (regno >= NDS32_FIRST_FPR_REGNUM
3355 && regno <= NDS32_LAST_FPR_REGNUM)
3356 {
3357 if (mode == DFmode || mode == SCmode)
3358 {
3359 /* By default, GCC maps increasing register numbers to increasing
3360 memory locations, but paired FPRs in NDS32 target are always
3361 big-endian, i.e.:
3362
3363 fd0 : fs0 fs1
3364 (MSB) (LSB)
3365
3366 We must return parallel rtx to represent such layout. */
3367 dwarf_high = gen_rtx_REG (word_mode, regno);
3368 dwarf_low = gen_rtx_REG (word_mode, regno + 1);
3369 return gen_rtx_PARALLEL (VOIDmode,
3370 gen_rtvec (2, dwarf_low, dwarf_high));
3371 }
3372 else if (mode == DCmode)
3373 {
3374 rtx dwarf_high_re = gen_rtx_REG (word_mode, regno);
3375 rtx dwarf_low_re = gen_rtx_REG (word_mode, regno + 1);
3376 rtx dwarf_high_im = gen_rtx_REG (word_mode, regno);
3377 rtx dwarf_low_im = gen_rtx_REG (word_mode, regno + 1);
3378 return gen_rtx_PARALLEL (VOIDmode,
3379 gen_rtvec (4, dwarf_low_re, dwarf_high_re,
3380 dwarf_high_im, dwarf_low_im));
3381 }
3382 else if (mode == SFmode || mode == SImode)
3383 {
3384 /* Create new dwarf information with adjusted register number. */
3385 dwarf_single = gen_rtx_REG (word_mode, regno);
3386 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, dwarf_single));
3387 }
3388 else
3389 {
3390 /* We should not be here. */
3391 gcc_unreachable ();
3392 }
3393 }
3394
3395 return NULL_RTX;
3396}
3397
3398/* Map internal gcc register numbers to DWARF2 register numbers. */
3399
3400unsigned int
3401nds32_dbx_register_number (unsigned int regno)
3402{
3403 /* The nds32 port in GDB maintains a mapping between dwarf register
3404 number and displayed register name. For backward compatibility to
3405 previous toolchain, currently our gdb still has four registers
3406 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3407 does not count those four registers in its register number table.
3408 So we have to add 4 on its register number and then create new
3409 dwarf information. Hopefully we can discard such workaround
3410 in the future. */
3411 if (NDS32_IS_FPR_REGNUM (regno))
3412 return regno + 4;
3413
3414 return regno;
3415}
3416
9304f876
CJW
3417\f
3418/* Defining target-specific uses of __attribute__. */
3419
3420/* Add some checking after merging attributes. */
3421static tree
3422nds32_merge_decl_attributes (tree olddecl, tree newdecl)
3423{
3424 tree combined_attrs;
3425
3426 /* Create combined attributes. */
3427 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
3428 DECL_ATTRIBUTES (newdecl));
3429
59043e75 3430 /* Since newdecl is acutally a duplicate of olddecl,
9304f876
CJW
3431 we can take olddecl for some operations. */
3432 if (TREE_CODE (olddecl) == FUNCTION_DECL)
3433 {
3434 /* Check isr-specific attributes conflict. */
3435 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
3436 }
3437
3438 return combined_attrs;
3439}
3440
3441/* Add some checking when inserting attributes. */
3442static void
3443nds32_insert_attributes (tree decl, tree *attributes)
3444{
3445 /* For function declaration, we need to check isr-specific attributes:
3446 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3447 2. Check valid integer value for interrupt/exception.
3448 3. Check valid integer value for reset.
3449 4. Check valid function for nmi/warm. */
3450 if (TREE_CODE (decl) == FUNCTION_DECL)
3451 {
3452 tree func_attrs;
3453 tree intr, excp, reset;
3454
3455 /* Pick up function attributes. */
3456 func_attrs = *attributes;
3457
3458 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3459 nds32_check_isr_attrs_conflict (decl, func_attrs);
3460
3461 /* Now we are starting to check valid id value
8a498f99
CJW
3462 for interrupt/exception/reset.
3463 Note that we ONLY check its validity here.
3464 To construct isr vector information, it is still performed
3465 by nds32_construct_isr_vectors_information(). */
9304f876
CJW
3466 intr = lookup_attribute ("interrupt", func_attrs);
3467 excp = lookup_attribute ("exception", func_attrs);
3468 reset = lookup_attribute ("reset", func_attrs);
3469
3470 if (intr || excp)
3471 {
3472 /* Deal with interrupt/exception. */
3473 tree id_list;
3474 unsigned int lower_bound, upper_bound;
3475
3476 /* The way to handle interrupt or exception is the same,
3477 we just need to take care of actual vector number.
3478 For interrupt(0..63), the actual vector number is (9..72).
3479 For exception(1..8), the actual vector number is (1..8). */
3480 lower_bound = (intr) ? (0) : (1);
3481 upper_bound = (intr) ? (63) : (8);
3482
3483 /* Prepare id list so that we can traverse id value. */
3484 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
3485
3486 /* 2. Check valid integer value for interrupt/exception. */
3487 while (id_list)
3488 {
3489 tree id;
3490
3491 /* Pick up each vector id value. */
3492 id = TREE_VALUE (id_list);
3493 /* Issue error if it is not a valid integer value. */
3494 if (TREE_CODE (id) != INTEGER_CST
8e6cdc90
RS
3495 || wi::ltu_p (wi::to_wide (id), lower_bound)
3496 || wi::gtu_p (wi::to_wide (id), upper_bound))
9304f876
CJW
3497 error ("invalid id value for interrupt/exception attribute");
3498
3499 /* Advance to next id. */
3500 id_list = TREE_CHAIN (id_list);
3501 }
3502 }
3503 else if (reset)
3504 {
3505 /* Deal with reset. */
3506 tree id_list;
3507 tree id;
3508 tree nmi, warm;
3509 unsigned int lower_bound;
3510 unsigned int upper_bound;
3511
3512 /* Prepare id_list and identify id value so that
3513 we can check if total number of vectors is valid. */
3514 id_list = TREE_VALUE (reset);
3515 id = TREE_VALUE (id_list);
3516
3517 /* The maximum numbers for user's interrupt is 64. */
3518 lower_bound = 0;
3519 upper_bound = 64;
3520
3521 /* 3. Check valid integer value for reset. */
3522 if (TREE_CODE (id) != INTEGER_CST
8e6cdc90
RS
3523 || wi::ltu_p (wi::to_wide (id), lower_bound)
3524 || wi::gtu_p (wi::to_wide (id), upper_bound))
9304f876
CJW
3525 error ("invalid id value for reset attribute");
3526
3527 /* 4. Check valid function for nmi/warm. */
3528 nmi = lookup_attribute ("nmi", func_attrs);
3529 warm = lookup_attribute ("warm", func_attrs);
3530
3531 if (nmi != NULL_TREE)
3532 {
3533 tree nmi_func_list;
3534 tree nmi_func;
3535
3536 nmi_func_list = TREE_VALUE (nmi);
3537 nmi_func = TREE_VALUE (nmi_func_list);
3538
3539 /* Issue error if it is not a valid nmi function. */
3540 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
3541 error ("invalid nmi function for reset attribute");
3542 }
3543
3544 if (warm != NULL_TREE)
3545 {
3546 tree warm_func_list;
3547 tree warm_func;
3548
3549 warm_func_list = TREE_VALUE (warm);
3550 warm_func = TREE_VALUE (warm_func_list);
3551
3552 /* Issue error if it is not a valid warm function. */
3553 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
3554 error ("invalid warm function for reset attribute");
3555 }
3556 }
3557 else
3558 {
3559 /* No interrupt, exception, or reset attribute is set. */
3560 return;
3561 }
3562 }
3563}
3564
3565static bool
3566nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
3567 tree pop_target ATTRIBUTE_UNUSED)
3568{
3569 /* Currently, we do not parse any pragma target by ourself,
3570 so just simply return false. */
3571 return false;
3572}
3573
3574static void
3575nds32_option_override (void)
3576{
3577 /* After all the command options have been parsed,
3578 we shall deal with some flags for changing compiler settings. */
3579
3580 /* At first, we check if we have to strictly
3581 set some flags based on ISA family. */
3582 if (TARGET_ISA_V2)
3583 {
3584 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
3585 target_flags &= ~MASK_V3PUSH;
3586 }
3587 if (TARGET_ISA_V3)
3588 {
3589 /* Under V3 ISA, currently nothing should be strictly set. */
3590 }
3591 if (TARGET_ISA_V3M)
3592 {
3593 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
3594 target_flags |= MASK_REDUCED_REGS;
aa4b851c
CJW
3595 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
3596 target_flags &= ~MASK_EXT_PERF;
3597 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
3598 target_flags &= ~MASK_EXT_PERF2;
3599 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
3600 target_flags &= ~MASK_EXT_STRING;
9304f876
CJW
3601 }
3602
3603 /* See if we are using reduced-set registers:
3604 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
3605 If so, we must forbid using $r11~$r14, $r16~$r27. */
3606 if (TARGET_REDUCED_REGS)
3607 {
3608 int r;
3609
3610 /* Prevent register allocator from
8a498f99 3611 choosing it as doing register allocation. */
9304f876
CJW
3612 for (r = 11; r <= 14; r++)
3613 fixed_regs[r] = call_used_regs[r] = 1;
3614 for (r = 16; r <= 27; r++)
3615 fixed_regs[r] = call_used_regs[r] = 1;
3616 }
3617
9304f876
CJW
3618 if (!TARGET_16_BIT)
3619 {
3620 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
3621 target_flags &= ~MASK_V3PUSH;
3622 }
3623
e2286268
MC
3624 if (TARGET_HARD_FLOAT && !(TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE))
3625 {
3626 if (nds32_arch_option == ARCH_V3S || nds32_arch_option == ARCH_V3F)
3627 error ("Disable FPU ISA, "
3628 "the ABI option must be enable '-mfloat-abi=soft'");
3629 else
3630 error ("'-mabi=2fp+' option only support when FPU available, "
3631 "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
3632 }
3633
9304f876
CJW
3634 /* Currently, we don't support PIC code generation yet. */
3635 if (flag_pic)
afd78f02 3636 sorry ("position-independent code not supported");
c4d8d050
CJW
3637
3638 nds32_register_passes ();
9304f876
CJW
3639}
3640
3641\f
3642/* Miscellaneous Parameters. */
3643
823835a9
CJW
3644static rtx_insn *
3645nds32_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
3646 vec<rtx> &inputs ATTRIBUTE_UNUSED,
3647 vec<const char *> &constraints ATTRIBUTE_UNUSED,
3648 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs)
3649{
3650 clobbers.safe_push (gen_rtx_REG (SImode, TA_REGNUM));
3651 SET_HARD_REG_BIT (clobbered_regs, TA_REGNUM);
3652 return NULL;
3653}
3654
9304f876
CJW
3655static void
3656nds32_init_builtins (void)
3657{
aaa44d2d 3658 nds32_init_builtins_impl ();
9304f876
CJW
3659}
3660
7a12ea32
MC
3661static tree
3662nds32_builtin_decl (unsigned code, bool initialize_p)
3663{
3664 /* Implement in nds32-intrinsic.c. */
3665 return nds32_builtin_decl_impl (code, initialize_p);
3666}
3667
9304f876
CJW
3668static rtx
3669nds32_expand_builtin (tree exp,
3670 rtx target,
aaa44d2d 3671 rtx subtarget,
ef4bddc2 3672 machine_mode mode,
aaa44d2d 3673 int ignore)
9304f876 3674{
aaa44d2d 3675 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
9304f876
CJW
3676}
3677
3678
3679/* ------------------------------------------------------------------------ */
3680
3681/* PART 4: Implemet extern function definitions,
3682 the prototype is in nds32-protos.h. */
72b7e5e1
KC
3683\f
3684/* Run-time Target Specification. */
3685
3686void
3687nds32_cpu_cpp_builtins(struct cpp_reader *pfile)
3688{
3689#define builtin_define(TXT) cpp_define (pfile, TXT)
3690#define builtin_assert(TXT) cpp_assert (pfile, TXT)
3691 builtin_define ("__nds32__");
3692 builtin_define ("__NDS32__");
3693
e2286268
MC
3694 if (TARGET_HARD_FLOAT)
3695 builtin_define ("__NDS32_ABI_2FP_PLUS__");
3696 else
3697 builtin_define ("__NDS32_ABI_2__");
3698
72b7e5e1
KC
3699 if (TARGET_ISA_V2)
3700 builtin_define ("__NDS32_ISA_V2__");
3701 if (TARGET_ISA_V3)
3702 builtin_define ("__NDS32_ISA_V3__");
3703 if (TARGET_ISA_V3M)
3704 builtin_define ("__NDS32_ISA_V3M__");
3705
e2286268
MC
3706 if (TARGET_FPU_SINGLE)
3707 builtin_define ("__NDS32_EXT_FPU_SP__");
3708 if (TARGET_FPU_DOUBLE)
3709 builtin_define ("__NDS32_EXT_FPU_DP__");
3710
3711 if (TARGET_EXT_FPU_FMA)
3712 builtin_define ("__NDS32_EXT_FPU_FMA__");
3713 if (NDS32_EXT_FPU_DOT_E)
3714 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
3715 if (TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
3716 {
3717 switch (nds32_fp_regnum)
3718 {
3719 case 0:
3720 case 4:
3721 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
3722 break;
3723 case 1:
3724 case 5:
3725 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
3726 break;
3727 case 2:
3728 case 6:
3729 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
3730 break;
3731 case 3:
3732 case 7:
3733 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
3734 break;
3735 default:
3736 abort ();
3737 }
3738 }
3739
72b7e5e1
KC
3740 if (TARGET_BIG_ENDIAN)
3741 builtin_define ("__NDS32_EB__");
3742 else
3743 builtin_define ("__NDS32_EL__");
3744
3745 if (TARGET_REDUCED_REGS)
3746 builtin_define ("__NDS32_REDUCED_REGS__");
3747 if (TARGET_CMOV)
3748 builtin_define ("__NDS32_CMOV__");
3749 if (TARGET_EXT_PERF)
3750 builtin_define ("__NDS32_EXT_PERF__");
3751 if (TARGET_EXT_PERF2)
3752 builtin_define ("__NDS32_EXT_PERF2__");
3753 if (TARGET_EXT_STRING)
3754 builtin_define ("__NDS32_EXT_STRING__");
3755 if (TARGET_16_BIT)
3756 builtin_define ("__NDS32_16_BIT__");
3757 if (TARGET_GP_DIRECT)
3758 builtin_define ("__NDS32_GP_DIRECT__");
ff77f6e8
KC
3759 if (TARGET_VH)
3760 builtin_define ("__NDS32_VH__");
72b7e5e1
KC
3761
3762 if (TARGET_BIG_ENDIAN)
3763 builtin_define ("__big_endian__");
3764
3765 builtin_assert ("cpu=nds32");
3766 builtin_assert ("machine=nds32");
e2286268
MC
3767
3768 if (TARGET_HARD_FLOAT)
3769 builtin_define ("__NDS32_ABI_2FP_PLUS");
3770 else
3771 builtin_define ("__NDS32_ABI_2");
3772
72b7e5e1
KC
3773#undef builtin_define
3774#undef builtin_assert
3775}
3776
9304f876
CJW
3777\f
3778/* Defining Data Structures for Per-function Information. */
3779
3780void
3781nds32_init_expanders (void)
3782{
3783 /* Arrange to initialize and mark the machine per-function status. */
3784 init_machine_status = nds32_init_machine_status;
3785}
3786
3787\f
3788/* Register Usage. */
3789
5e6ae0cc
CJW
3790/* -- Order of Allocation of Registers. */
3791
3792void
3793nds32_adjust_reg_alloc_order (void)
3794{
3795 const int nds32_reg_alloc_order[] = REG_ALLOC_ORDER;
3796
3797 /* Copy the default register allocation order, which is designed
3798 to optimize for code size. */
3799 memcpy(reg_alloc_order, nds32_reg_alloc_order, sizeof (reg_alloc_order));
3800
3801 /* Adjust few register allocation order when optimizing for speed. */
3802 if (!optimize_size)
3803 {
3804 memcpy (reg_alloc_order, nds32_reg_alloc_order_for_speed,
3805 sizeof (nds32_reg_alloc_order_for_speed));
3806 }
3807}
3808
9304f876
CJW
3809/* -- How Values Fit in Registers. */
3810
e2286268
MC
3811static unsigned
3812nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED,
3813 machine_mode mode)
3814{
3815 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
3816}
3817
f939c3e6
RS
3818/* Implement TARGET_HARD_REGNO_MODE_OK. */
3819
3820static bool
3821nds32_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
9304f876 3822{
e2286268 3823 if (regno > FIRST_PSEUDO_REGISTER)
f939c3e6 3824 return true;
9304f876 3825
e2286268
MC
3826 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE) && NDS32_IS_FPR_REGNUM (regno))
3827 {
3828 if (NDS32_IS_EXT_FPR_REGNUM(regno))
3829 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno) && (mode == DFmode));
3830 else if (mode == SFmode || mode == SImode)
3831 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno);
3832 else if (mode == DFmode)
3833 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno);
3834
3835 return false;
3836 }
3837
3838 /* Restrict double-word quantities to even register pairs. */
3839 if (regno <= NDS32_LAST_GPR_REGNUM)
3840 return (targetm.hard_regno_nregs (regno, mode) == 1
3841 || !((regno) & 1));
3842
f939c3e6 3843 return false;
9304f876
CJW
3844}
3845
99e1629f
RS
3846/* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
3847 tie QI/HI/SI modes together. */
3848
3849static bool
3850nds32_modes_tieable_p (machine_mode mode1, machine_mode mode2)
3851{
e2286268
MC
3852 if ((GET_MODE_CLASS (mode1) == MODE_INT
3853 && GET_MODE_CLASS (mode2) == MODE_INT)
3854 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
3855 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD)
3856 return true;
3857
3858 if (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2))
3859 {
3860 if ((TARGET_FPU_SINGLE && !TARGET_FPU_DOUBLE)
3861 && (mode1 == DFmode || mode2 == DFmode))
3862 return false;
3863 else
3864 return true;
3865 }
3866
3867 return false;
99e1629f 3868}
9304f876
CJW
3869\f
3870/* Register Classes. */
3871
3872enum reg_class
3873nds32_regno_reg_class (int regno)
3874{
3875 /* Refer to nds32.h for more register class details. */
3876
3877 if (regno >= 0 && regno <= 7)
3878 return LOW_REGS;
3879 else if (regno >= 8 && regno <= 11)
3880 return MIDDLE_REGS;
3881 else if (regno >= 12 && regno <= 14)
3882 return HIGH_REGS;
3883 else if (regno == 15)
3884 return R15_TA_REG;
3885 else if (regno >= 16 && regno <= 19)
3886 return MIDDLE_REGS;
3887 else if (regno >= 20 && regno <= 31)
3888 return HIGH_REGS;
3889 else if (regno == 32 || regno == 33)
e2286268
MC
3890 {
3891 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
3892 know how to allocate register for $SFP and $AP, just tell IRA they
3893 are GENERAL_REGS, and ARM do this hack too. */
3894 return GENERAL_REGS;
3895 }
3896 else if (regno >= 34 && regno <= 97)
3897 return FP_REGS;
9304f876
CJW
3898 else
3899 return NO_REGS;
3900}
3901
3902\f
3903/* Stack Layout and Calling Conventions. */
3904
3905/* -- Basic Stack Layout. */
3906
ca3a4a55
CJW
3907rtx
3908nds32_dynamic_chain_address (rtx frameaddr)
3909{
3910 if (TARGET_V3PUSH)
3911 {
3912 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
3913 We can access dynamic chain address from stack by [$fp - 12]. */
3914 return plus_constant (Pmode, frameaddr, -12);
3915 }
3916 else
3917 {
3918 /* For general case we push $fp and $lp into stack at prologue.
3919 We can access dynamic chain address from stack by [$fp - 8]. */
3920 return plus_constant (Pmode, frameaddr, -8);
3921 }
3922}
3923
9304f876
CJW
3924rtx
3925nds32_return_addr_rtx (int count,
ca3a4a55 3926 rtx frameaddr)
9304f876 3927{
ca3a4a55
CJW
3928 int offset;
3929 rtx addr;
3930
9304f876 3931 if (count != 0)
ca3a4a55
CJW
3932 {
3933 /* In nds32 ABI design, we can expect that $lp is always available
3934 from stack by [$fp - 4] location. */
3935 offset = -4;
3936 addr = plus_constant (Pmode, frameaddr, offset);
3937 addr = memory_address (Pmode, addr);
3938
3939 return gen_rtx_MEM (Pmode, addr);
3940 }
9304f876
CJW
3941
3942 /* If count == 0, it means we are at current frame,
3943 the return address is $r30 ($lp). */
3944 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
3945}
3946
3947/* -- Eliminating Frame Pointer and Arg Pointer. */
3948
3949HOST_WIDE_INT
3950nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
3951{
3952 HOST_WIDE_INT offset;
3953
3954 /* Compute and setup stack frame size.
3955 The result will be in cfun->machine. */
3956 nds32_compute_stack_frame ();
3957
3958 /* Remember to consider
ca3a4a55
CJW
3959 cfun->machine->callee_saved_area_gpr_padding_bytes and
3960 cfun->machine->eh_return_data_regs_size
9304f876
CJW
3961 when calculating offset. */
3962 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
3963 {
3964 offset = (cfun->machine->fp_size
8a498f99 3965 + cfun->machine->gp_size
9304f876 3966 + cfun->machine->lp_size
c457f751
CJW
3967 + cfun->machine->callee_saved_gpr_regs_size
3968 + cfun->machine->callee_saved_area_gpr_padding_bytes
e2286268 3969 + cfun->machine->callee_saved_fpr_regs_size
ca3a4a55 3970 + cfun->machine->eh_return_data_regs_size
9304f876
CJW
3971 + cfun->machine->local_size
3972 + cfun->machine->out_args_size);
3973 }
3974 else if (from_reg == ARG_POINTER_REGNUM
3975 && to_reg == HARD_FRAME_POINTER_REGNUM)
3976 {
3977 offset = 0;
3978 }
3979 else if (from_reg == FRAME_POINTER_REGNUM
3980 && to_reg == STACK_POINTER_REGNUM)
3981 {
3982 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
3983 }
3984 else if (from_reg == FRAME_POINTER_REGNUM
3985 && to_reg == HARD_FRAME_POINTER_REGNUM)
3986 {
3987 offset = (-1) * (cfun->machine->fp_size
3988 + cfun->machine->gp_size
3989 + cfun->machine->lp_size
c457f751 3990 + cfun->machine->callee_saved_gpr_regs_size
e2286268 3991 + cfun->machine->callee_saved_area_gpr_padding_bytes
ca3a4a55
CJW
3992 + cfun->machine->callee_saved_fpr_regs_size
3993 + cfun->machine->eh_return_data_regs_size);
9304f876
CJW
3994 }
3995 else
3996 {
3997 gcc_unreachable ();
3998 }
3999
4000 return offset;
4001}
4002
4003/* -- Passing Arguments in Registers. */
4004
4005void
4006nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
4007 tree fntype ATTRIBUTE_UNUSED,
4008 rtx libname ATTRIBUTE_UNUSED,
4009 tree fndecl ATTRIBUTE_UNUSED,
4010 int n_named_args ATTRIBUTE_UNUSED)
4011{
e2286268
MC
4012 /* Initial available registers. The values are offset against
4013 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
9304f876 4014 for passing arguments. */
9d93cc24 4015 cum->gpr_offset = 0;
e2286268 4016 cum->fpr_offset = 0;
9304f876
CJW
4017}
4018
4019/* -- Function Entry and Exit. */
4020
4021/* Function for normal multiple push prologue. */
4022void
4023nds32_expand_prologue (void)
4024{
4025 int fp_adjust;
4026 int sp_adjust;
a6c7e777 4027 unsigned Rb, Re;
9304f876 4028
9304f876
CJW
4029 /* Compute and setup stack frame size.
4030 The result will be in cfun->machine. */
4031 nds32_compute_stack_frame ();
4032
557430f1
CJW
4033 /* If this is a variadic function, first we need to push argument
4034 registers that hold the unnamed argument value. */
4035 if (cfun->machine->va_args_size != 0)
4036 {
a6c7e777
MC
4037 Rb = cfun->machine->va_args_first_regno;
4038 Re = cfun->machine->va_args_last_regno;
4039 /* No need to push $fp, $gp, or $lp. */
4040 nds32_emit_stack_push_multiple (Rb, Re, false, false, false, true);
557430f1
CJW
4041
4042 /* We may also need to adjust stack pointer for padding bytes
4043 because varargs may cause $sp not 8-byte aligned. */
4044 if (cfun->machine->va_args_area_padding_bytes)
4045 {
4046 /* Generate sp adjustment instruction. */
4047 sp_adjust = cfun->machine->va_args_area_padding_bytes;
557430f1 4048
a6c7e777
MC
4049 nds32_emit_adjust_frame (stack_pointer_rtx,
4050 stack_pointer_rtx,
4051 -1 * sp_adjust);
557430f1
CJW
4052 }
4053 }
4054
9304f876
CJW
4055 /* If the function is 'naked',
4056 we do not have to generate prologue code fragment. */
4057 if (cfun->machine->naked_p)
4058 return;
4059
4060 /* Get callee_first_regno and callee_last_regno. */
a6c7e777
MC
4061 Rb = cfun->machine->callee_saved_first_gpr_regno;
4062 Re = cfun->machine->callee_saved_last_gpr_regno;
9304f876
CJW
4063
4064 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4065 to be saved, we don't have to create multiple push instruction.
4066 Otherwise, a multiple push instruction is needed. */
a6c7e777
MC
4067 if (!(Rb == SP_REGNUM && Re == SP_REGNUM
4068 && cfun->machine->fp_size == 0
4069 && cfun->machine->gp_size == 0
4070 && cfun->machine->lp_size == 0))
9304f876
CJW
4071 {
4072 /* Create multiple push instruction rtx. */
a6c7e777
MC
4073 nds32_emit_stack_push_multiple (
4074 Rb, Re,
4075 cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size,
4076 false);
9304f876
CJW
4077 }
4078
ca3a4a55
CJW
4079 /* Save eh data registers. */
4080 if (cfun->machine->use_eh_return_p)
4081 {
4082 Rb = cfun->machine->eh_return_data_first_regno;
4083 Re = cfun->machine->eh_return_data_last_regno;
4084
4085 /* No need to push $fp, $gp, or $lp.
4086 Also, this is not variadic arguments push. */
4087 nds32_emit_stack_push_multiple (Rb, Re, false, false, false, false);
4088 }
4089
9304f876
CJW
4090 /* Check frame_pointer_needed to see
4091 if we shall emit fp adjustment instruction. */
4092 if (frame_pointer_needed)
4093 {
4094 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
8a498f99 4095 + (4 * callee-saved-registers)
ca3a4a55 4096 + (4 * exception-handling-data-registers)
8a498f99
CJW
4097 Note: No need to adjust
4098 cfun->machine->callee_saved_area_gpr_padding_bytes,
4099 because, at this point, stack pointer is just
4100 at the position after push instruction. */
9304f876
CJW
4101 fp_adjust = cfun->machine->fp_size
4102 + cfun->machine->gp_size
4103 + cfun->machine->lp_size
ca3a4a55
CJW
4104 + cfun->machine->callee_saved_gpr_regs_size
4105 + cfun->machine->eh_return_data_regs_size;
7064dcad 4106
a6c7e777
MC
4107 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
4108 stack_pointer_rtx,
4109 fp_adjust);
9304f876
CJW
4110 }
4111
e2286268
MC
4112 /* Save fpu registers. */
4113 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4114 {
4115 /* When $sp moved to bottom of stack, we need to check whether
4116 the range of offset in the FPU instruction. */
4117 int fpr_offset = cfun->machine->local_size
4118 + cfun->machine->out_args_size
4119 + cfun->machine->callee_saved_fpr_regs_size;
4120
4121 /* Check FPU instruction offset imm14s. */
4122 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset)))
4123 {
4124 int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
4125 + cfun->machine->callee_saved_fpr_regs_size;
4126
4127 /* Save fpu registers, need to allocate stack space
4128 for fpu callee registers. And now $sp position
4129 on callee saved fpr registers. */
4130 nds32_emit_adjust_frame (stack_pointer_rtx,
4131 stack_pointer_rtx,
4132 -1 * fpr_space);
4133
4134 /* Emit fpu store instruction, using [$sp + offset] store
4135 fpu registers. */
4136 nds32_emit_push_fpr_callee_saved (0);
4137
4138 /* Adjust $sp = $sp - local_size - out_args_size. */
4139 sp_adjust = cfun->machine->local_size
4140 + cfun->machine->out_args_size;
4141
4142 /* Allocate stack space for local size and out args size. */
4143 nds32_emit_adjust_frame (stack_pointer_rtx,
4144 stack_pointer_rtx,
4145 -1 * sp_adjust);
4146 }
4147 else
4148 {
4149 /* Offset range in Is14, so $sp moved to bottom of stack. */
4150
4151 /* Adjust $sp = $sp - local_size - out_args_size
4152 - callee_saved_area_gpr_padding_bytes
4153 - callee_saved_fpr_regs_size. */
4154 sp_adjust = cfun->machine->local_size
4155 + cfun->machine->out_args_size
4156 + cfun->machine->callee_saved_area_gpr_padding_bytes
4157 + cfun->machine->callee_saved_fpr_regs_size;
4158
4159 nds32_emit_adjust_frame (stack_pointer_rtx,
4160 stack_pointer_rtx,
4161 -1 * sp_adjust);
4162
4163 /* Emit fpu store instruction, using [$sp + offset] store
4164 fpu registers. */
4165 int fpr_position = cfun->machine->out_args_size
4166 + cfun->machine->local_size;
4167 nds32_emit_push_fpr_callee_saved (fpr_position);
4168 }
4169 }
4170 else
4171 {
4172 /* Adjust $sp = $sp - local_size - out_args_size
4173 - callee_saved_area_gpr_padding_bytes. */
4174 sp_adjust = cfun->machine->local_size
4175 + cfun->machine->out_args_size
4176 + cfun->machine->callee_saved_area_gpr_padding_bytes;
4177
4178 /* sp_adjust value may be out of range of the addi instruction,
4179 create alternative add behavior with TA_REGNUM if necessary,
4180 using NEGATIVE value to tell that we are decreasing address. */
4181 nds32_emit_adjust_frame (stack_pointer_rtx,
4182 stack_pointer_rtx,
4183 -1 * sp_adjust);
4184 }
9304f876
CJW
4185
4186 /* Prevent the instruction scheduler from
4187 moving instructions across the boundary. */
4188 emit_insn (gen_blockage ());
4189}
4190
4191/* Function for normal multiple pop epilogue. */
4192void
d6529176 4193nds32_expand_epilogue (bool sibcall_p)
9304f876
CJW
4194{
4195 int sp_adjust;
a6c7e777 4196 unsigned Rb, Re;
9304f876
CJW
4197
4198 /* Compute and setup stack frame size.
4199 The result will be in cfun->machine. */
4200 nds32_compute_stack_frame ();
4201
4202 /* Prevent the instruction scheduler from
4203 moving instructions across the boundary. */
4204 emit_insn (gen_blockage ());
4205
4206 /* If the function is 'naked', we do not have to generate
557430f1
CJW
4207 epilogue code fragment BUT 'ret' instruction.
4208 However, if this function is also a variadic function,
4209 we need to create adjust stack pointer before 'ret' instruction. */
9304f876
CJW
4210 if (cfun->machine->naked_p)
4211 {
557430f1 4212 /* If this is a variadic function, we do not have to restore argument
8a498f99
CJW
4213 registers but need to adjust stack pointer back to previous stack
4214 frame location before return. */
557430f1
CJW
4215 if (cfun->machine->va_args_size != 0)
4216 {
4217 /* Generate sp adjustment instruction.
4218 We need to consider padding bytes here. */
4219 sp_adjust = cfun->machine->va_args_size
4220 + cfun->machine->va_args_area_padding_bytes;
a6c7e777
MC
4221
4222 nds32_emit_adjust_frame (stack_pointer_rtx,
4223 stack_pointer_rtx,
4224 sp_adjust);
557430f1
CJW
4225 }
4226
03390cda 4227 /* Generate return instruction by using 'return_internal' pattern.
8a498f99 4228 Make sure this instruction is after gen_blockage(). */
d6529176
CJW
4229 if (!sibcall_p)
4230 emit_jump_insn (gen_return_internal ());
9304f876
CJW
4231 return;
4232 }
4233
4234 if (frame_pointer_needed)
4235 {
e2286268
MC
4236 /* Restore fpu registers. */
4237 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4238 {
4239 int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes;
4240
4241 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4242 - (4 * callee-saved-registers)
4243 - (4 * exception-handling-data-registers)
4244 - (4 * callee-saved-gpr-registers padding byte)
4245 - (4 * callee-saved-fpr-registers)
4246 Note: we want to adjust stack pointer
4247 to the position for callee-saved fpr register,
4248 And restore fpu register use .bi instruction to adjust $sp
4249 from callee-saved fpr register to pop instruction. */
4250 sp_adjust = cfun->machine->fp_size
4251 + cfun->machine->gp_size
4252 + cfun->machine->lp_size
4253 + cfun->machine->callee_saved_gpr_regs_size
ca3a4a55 4254 + cfun->machine->eh_return_data_regs_size
e2286268
MC
4255 + cfun->machine->callee_saved_area_gpr_padding_bytes
4256 + cfun->machine->callee_saved_fpr_regs_size;
557430f1 4257
e2286268
MC
4258 nds32_emit_adjust_frame (stack_pointer_rtx,
4259 hard_frame_pointer_rtx,
4260 -1 * sp_adjust);
4261
4262 /* Emit fpu load instruction, using .bi instruction
4263 load fpu registers. */
4264 nds32_emit_pop_fpr_callee_saved (gpr_padding);
4265 }
4266 else
4267 {
4268 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4269 - (4 * callee-saved-registers)
4270 - (4 * exception-handling-data-registers)
4271 Note: No need to adjust
4272 cfun->machine->callee_saved_area_gpr_padding_bytes,
4273 because we want to adjust stack pointer
4274 to the position for pop instruction. */
4275 sp_adjust = cfun->machine->fp_size
4276 + cfun->machine->gp_size
4277 + cfun->machine->lp_size
ca3a4a55
CJW
4278 + cfun->machine->callee_saved_gpr_regs_size
4279 + cfun->machine->eh_return_data_regs_size;
e2286268
MC
4280
4281 nds32_emit_adjust_frame (stack_pointer_rtx,
4282 hard_frame_pointer_rtx,
4283 -1 * sp_adjust);
4284 }
9304f876
CJW
4285 }
4286 else
4287 {
e2286268
MC
4288 /* Restore fpu registers. */
4289 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4290 {
4291 int gpr_padding = cfun->machine->callee_saved_area_gpr_padding_bytes;
9304f876 4292
e2286268
MC
4293 /* Adjust $sp = $sp + local_size + out_args_size. */
4294 sp_adjust = cfun->machine->local_size
4295 + cfun->machine->out_args_size;
a6c7e777 4296
e2286268
MC
4297 nds32_emit_adjust_frame (stack_pointer_rtx,
4298 stack_pointer_rtx,
4299 sp_adjust);
4300
4301 /* Emit fpu load instruction, using .bi instruction
4302 load fpu registers, and adjust $sp from callee-saved fpr register
4303 to callee-saved gpr register. */
4304 nds32_emit_pop_fpr_callee_saved (gpr_padding);
4305 }
4306 else
4307 {
4308 /* If frame pointer is NOT needed,
4309 we cannot calculate the sp adjustment from frame pointer.
4310 Instead, we calculate the adjustment by local_size,
4311 out_args_size, and callee_saved_area_gpr_padding_bytes.
4312 Notice that such sp adjustment value may be out of range,
4313 so we have to deal with it as well. */
4314
4315 /* Adjust $sp = $sp + local_size + out_args_size
4316 + callee_saved_area_gpr_padding_bytes. */
4317 sp_adjust = cfun->machine->local_size
4318 + cfun->machine->out_args_size
4319 + cfun->machine->callee_saved_area_gpr_padding_bytes;
4320
4321 nds32_emit_adjust_frame (stack_pointer_rtx,
4322 stack_pointer_rtx,
4323 sp_adjust);
4324 }
9304f876
CJW
4325 }
4326
ca3a4a55
CJW
4327 /* Restore eh data registers. */
4328 if (cfun->machine->use_eh_return_p)
4329 {
4330 Rb = cfun->machine->eh_return_data_first_regno;
4331 Re = cfun->machine->eh_return_data_last_regno;
4332
4333 /* No need to pop $fp, $gp, or $lp. */
4334 nds32_emit_stack_pop_multiple (Rb, Re, false, false, false);
4335 }
4336
9304f876 4337 /* Get callee_first_regno and callee_last_regno. */
a6c7e777
MC
4338 Rb = cfun->machine->callee_saved_first_gpr_regno;
4339 Re = cfun->machine->callee_saved_last_gpr_regno;
9304f876
CJW
4340
4341 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4342 to be saved, we don't have to create multiple pop instruction.
4343 Otherwise, a multiple pop instruction is needed. */
a6c7e777
MC
4344 if (!(Rb == SP_REGNUM && Re == SP_REGNUM
4345 && cfun->machine->fp_size == 0
4346 && cfun->machine->gp_size == 0
4347 && cfun->machine->lp_size == 0))
9304f876
CJW
4348 {
4349 /* Create multiple pop instruction rtx. */
a6c7e777
MC
4350 nds32_emit_stack_pop_multiple (
4351 Rb, Re,
4352 cfun->machine->fp_size, cfun->machine->gp_size, cfun->machine->lp_size);
9304f876
CJW
4353 }
4354
557430f1
CJW
4355 /* If this is a variadic function, we do not have to restore argument
4356 registers but need to adjust stack pointer back to previous stack
4357 frame location before return. */
4358 if (cfun->machine->va_args_size != 0)
4359 {
4360 /* Generate sp adjustment instruction.
8a498f99 4361 We need to consider padding bytes here. */
557430f1
CJW
4362 sp_adjust = cfun->machine->va_args_size
4363 + cfun->machine->va_args_area_padding_bytes;
557430f1 4364
a6c7e777
MC
4365 nds32_emit_adjust_frame (stack_pointer_rtx,
4366 stack_pointer_rtx,
4367 sp_adjust);
557430f1
CJW
4368 }
4369
ca3a4a55
CJW
4370 /* If this function uses __builtin_eh_return, make stack adjustment
4371 for exception handler. */
4372 if (cfun->machine->use_eh_return_p)
4373 {
4374 /* We need to unwind the stack by the offset computed by
4375 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4376 based on SP. Ideally we would update the SP and define the
4377 CFA along the lines of:
4378
4379 SP = SP + EH_RETURN_STACKADJ_RTX
4380 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4381
4382 However the dwarf emitter only understands a constant
4383 register offset.
4384
4385 The solution chosen here is to use the otherwise $ta ($r15)
4386 as a temporary register to hold the current SP value. The
4387 CFA is described using $ta then SP is modified. */
4388
4389 rtx ta_reg;
4390 rtx insn;
4391
4392 ta_reg = gen_rtx_REG (SImode, TA_REGNUM);
4393
4394 insn = emit_move_insn (ta_reg, stack_pointer_rtx);
4395 add_reg_note (insn, REG_CFA_DEF_CFA, ta_reg);
4396 RTX_FRAME_RELATED_P (insn) = 1;
4397
4398 emit_insn (gen_addsi3 (stack_pointer_rtx,
4399 stack_pointer_rtx,
4400 EH_RETURN_STACKADJ_RTX));
4401
4402 /* Ensure the assignment to $ta does not get optimized away. */
4403 emit_use (ta_reg);
4404 }
4405
03390cda 4406 /* Generate return instruction. */
d6529176
CJW
4407 if (!sibcall_p)
4408 emit_jump_insn (gen_return_internal ());
9304f876
CJW
4409}
4410
4411/* Function for v3push prologue. */
4412void
4413nds32_expand_prologue_v3push (void)
4414{
4415 int fp_adjust;
4416 int sp_adjust;
e2286268 4417 int fpr_space = 0;
a6c7e777 4418 unsigned Rb, Re;
9304f876 4419
9304f876
CJW
4420 /* Compute and setup stack frame size.
4421 The result will be in cfun->machine. */
4422 nds32_compute_stack_frame ();
4423
a6c7e777
MC
4424 if (cfun->machine->callee_saved_gpr_regs_size > 0)
4425 df_set_regs_ever_live (FP_REGNUM, 1);
4426
9304f876
CJW
4427 /* If the function is 'naked',
4428 we do not have to generate prologue code fragment. */
4429 if (cfun->machine->naked_p)
4430 return;
4431
4432 /* Get callee_first_regno and callee_last_regno. */
a6c7e777
MC
4433 Rb = cfun->machine->callee_saved_first_gpr_regno;
4434 Re = cfun->machine->callee_saved_last_gpr_regno;
9304f876
CJW
4435
4436 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
4437 where imm8u has to be 8-byte alignment. */
4438 sp_adjust = cfun->machine->local_size
4439 + cfun->machine->out_args_size
e2286268
MC
4440 + cfun->machine->callee_saved_area_gpr_padding_bytes
4441 + cfun->machine->callee_saved_fpr_regs_size;
9304f876
CJW
4442
4443 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
4444 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
4445 {
4446 /* We can use 'push25 Re,imm8u'. */
4447
88437f39 4448 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
a6c7e777
MC
4449 the pattern 'stack_v3push' is implemented in nds32.md. */
4450 nds32_emit_stack_v3push (Rb, Re, sp_adjust);
e2286268
MC
4451
4452 /* Save fpu registers. */
4453 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4454 {
4455 /* Calculate fpr position. */
4456 int fpr_position = cfun->machine->local_size
4457 + cfun->machine->out_args_size;
4458 /* Emit fpu store instruction, using [$sp + offset] store
4459 fpu registers. */
4460 nds32_emit_push_fpr_callee_saved (fpr_position);
4461 }
4462
9304f876 4463 /* Check frame_pointer_needed to see
8a498f99 4464 if we shall emit fp adjustment instruction. */
9304f876
CJW
4465 if (frame_pointer_needed)
4466 {
4467 /* adjust $fp = $sp + 4 ($fp size)
8a498f99
CJW
4468 + 4 ($gp size)
4469 + 4 ($lp size)
4470 + (4 * n) (callee-saved registers)
4471 + sp_adjust ('push25 Re,imm8u')
9304f876 4472 Note: Since we use 'push25 Re,imm8u',
8a498f99
CJW
4473 the position of stack pointer is further
4474 changed after push instruction.
4475 Hence, we need to take sp_adjust value
4476 into consideration. */
9304f876
CJW
4477 fp_adjust = cfun->machine->fp_size
4478 + cfun->machine->gp_size
4479 + cfun->machine->lp_size
c457f751 4480 + cfun->machine->callee_saved_gpr_regs_size
9304f876 4481 + sp_adjust;
a6c7e777
MC
4482
4483 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
4484 stack_pointer_rtx,
4485 fp_adjust);
9304f876
CJW
4486 }
4487 }
4488 else
4489 {
e2286268
MC
4490 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4491 {
4492 /* Calculate fpr space. */
4493 fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
4494 + cfun->machine->callee_saved_fpr_regs_size;
4495
4496 /* We have to use 'push25 Re, fpr_space', to pre-allocate
4497 callee saved fpr registers space. */
4498 nds32_emit_stack_v3push (Rb, Re, fpr_space);
4499 nds32_emit_push_fpr_callee_saved (0);
4500 }
4501 else
4502 {
4503 /* We have to use 'push25 Re,0' and
4504 expand one more instruction to adjust $sp later. */
9304f876 4505
e2286268
MC
4506 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4507 the pattern 'stack_v3push' is implemented in nds32.md. */
4508 nds32_emit_stack_v3push (Rb, Re, 0);
4509 }
9304f876
CJW
4510
4511 /* Check frame_pointer_needed to see
8a498f99 4512 if we shall emit fp adjustment instruction. */
9304f876
CJW
4513 if (frame_pointer_needed)
4514 {
4515 /* adjust $fp = $sp + 4 ($fp size)
8a498f99
CJW
4516 + 4 ($gp size)
4517 + 4 ($lp size)
4518 + (4 * n) (callee-saved registers)
9304f876 4519 Note: Since we use 'push25 Re,0',
8a498f99
CJW
4520 the stack pointer is just at the position
4521 after push instruction.
4522 No need to take sp_adjust into consideration. */
9304f876
CJW
4523 fp_adjust = cfun->machine->fp_size
4524 + cfun->machine->gp_size
4525 + cfun->machine->lp_size
c457f751 4526 + cfun->machine->callee_saved_gpr_regs_size;
a6c7e777 4527
e2286268
MC
4528 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4529 {
4530 /* We use 'push25 Re, fpr_space', the $sp is
4531 on callee saved fpr position, so need to consider
4532 fpr space. */
4533 fp_adjust = fp_adjust + fpr_space;
4534 }
4535
a6c7e777
MC
4536 nds32_emit_adjust_frame (hard_frame_pointer_rtx,
4537 stack_pointer_rtx,
4538 fp_adjust);
9304f876
CJW
4539 }
4540
e2286268
MC
4541 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4542 {
4543 /* We use 'push25 Re, fpr_space',
4544 the $sp is on callee saved fpr position,
4545 no need to consider fpr space. */
4546 sp_adjust = sp_adjust - fpr_space;
4547 }
4548
9304f876 4549 /* Because we use 'push25 Re,0',
8a498f99 4550 we need to expand one more instruction to adjust $sp.
8a498f99 4551 using NEGATIVE value to tell that we are decreasing address. */
a6c7e777
MC
4552 nds32_emit_adjust_frame (stack_pointer_rtx,
4553 stack_pointer_rtx,
4554 -1 * sp_adjust);
9304f876
CJW
4555 }
4556
4557 /* Prevent the instruction scheduler from
4558 moving instructions across the boundary. */
4559 emit_insn (gen_blockage ());
4560}
4561
4562/* Function for v3pop epilogue. */
4563void
d6529176 4564nds32_expand_epilogue_v3pop (bool sibcall_p)
9304f876
CJW
4565{
4566 int sp_adjust;
a6c7e777 4567 unsigned Rb, Re;
9304f876
CJW
4568
4569 /* Compute and setup stack frame size.
4570 The result will be in cfun->machine. */
4571 nds32_compute_stack_frame ();
4572
4573 /* Prevent the instruction scheduler from
4574 moving instructions across the boundary. */
4575 emit_insn (gen_blockage ());
4576
4577 /* If the function is 'naked', we do not have to generate
4578 epilogue code fragment BUT 'ret' instruction. */
4579 if (cfun->machine->naked_p)
4580 {
03390cda 4581 /* Generate return instruction by using 'return_internal' pattern.
8a498f99 4582 Make sure this instruction is after gen_blockage(). */
d6529176
CJW
4583 if (!sibcall_p)
4584 emit_jump_insn (gen_return_internal ());
9304f876
CJW
4585 return;
4586 }
4587
4588 /* Get callee_first_regno and callee_last_regno. */
a6c7e777
MC
4589 Rb = cfun->machine->callee_saved_first_gpr_regno;
4590 Re = cfun->machine->callee_saved_last_gpr_regno;
9304f876
CJW
4591
4592 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
4593 where imm8u has to be 8-byte alignment. */
4594 sp_adjust = cfun->machine->local_size
4595 + cfun->machine->out_args_size
e2286268
MC
4596 + cfun->machine->callee_saved_area_gpr_padding_bytes
4597 + cfun->machine->callee_saved_fpr_regs_size;
9304f876
CJW
4598
4599 /* We have to consider alloca issue as well.
4600 If the function does call alloca(), the stack pointer is not fixed.
4601 In that case, we cannot use 'pop25 Re,imm8u' directly.
4602 We have to caculate stack pointer from frame pointer
4603 and then use 'pop25 Re,0'.
4604 Of course, the frame_pointer_needed should be nonzero
4605 if the function calls alloca(). */
4606 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
4607 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
4608 && !cfun->calls_alloca)
4609 {
e2286268
MC
4610 /* Restore fpu registers. */
4611 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4612 {
4613 int fpr_position = cfun->machine->local_size
4614 + cfun->machine->out_args_size;
4615 /* Emit fpu load instruction, using [$sp + offset] restore
4616 fpu registers. */
4617 nds32_emit_v3pop_fpr_callee_saved (fpr_position);
4618 }
4619
9304f876
CJW
4620 /* We can use 'pop25 Re,imm8u'. */
4621
88437f39 4622 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
a6c7e777
MC
4623 the pattern 'stack_v3pop' is implementad in nds32.md. */
4624 nds32_emit_stack_v3pop (Rb, Re, sp_adjust);
9304f876
CJW
4625 }
4626 else
4627 {
4628 /* We have to use 'pop25 Re,0', and prior to it,
8a498f99 4629 we must expand one more instruction to adjust $sp. */
9304f876
CJW
4630
4631 if (frame_pointer_needed)
4632 {
4633 /* adjust $sp = $fp - 4 ($fp size)
8a498f99
CJW
4634 - 4 ($gp size)
4635 - 4 ($lp size)
4636 - (4 * n) (callee-saved registers)
9304f876 4637 Note: No need to adjust
8a498f99
CJW
4638 cfun->machine->callee_saved_area_gpr_padding_bytes,
4639 because we want to adjust stack pointer
4640 to the position for pop instruction. */
9304f876
CJW
4641 sp_adjust = cfun->machine->fp_size
4642 + cfun->machine->gp_size
4643 + cfun->machine->lp_size
c457f751 4644 + cfun->machine->callee_saved_gpr_regs_size;
a6c7e777 4645
e2286268
MC
4646 /* Restore fpu registers. */
4647 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4648 {
4649 /* Set $sp to callee saved fpr position, we need to restore
4650 fpr registers. */
4651 sp_adjust = sp_adjust
4652 + cfun->machine->callee_saved_area_gpr_padding_bytes
4653 + cfun->machine->callee_saved_fpr_regs_size;
4654
4655 nds32_emit_adjust_frame (stack_pointer_rtx,
4656 hard_frame_pointer_rtx,
4657 -1 * sp_adjust);
4658
4659 /* Emit fpu load instruction, using [$sp + offset] restore
4660 fpu registers. */
4661 nds32_emit_v3pop_fpr_callee_saved (0);
4662 }
4663 else
4664 {
4665 nds32_emit_adjust_frame (stack_pointer_rtx,
4666 hard_frame_pointer_rtx,
4667 -1 * sp_adjust);
4668 }
9304f876
CJW
4669 }
4670 else
4671 {
4672 /* If frame pointer is NOT needed,
4673 we cannot calculate the sp adjustment from frame pointer.
4674 Instead, we calculate the adjustment by local_size,
4675 out_args_size, and callee_saved_area_padding_bytes.
4676 Notice that such sp adjustment value may be out of range,
4677 so we have to deal with it as well. */
4678
4679 /* Adjust $sp = $sp + local_size + out_args_size
e2286268
MC
4680 + callee_saved_area_gpr_padding_bytes
4681 + callee_saved_fpr_regs_size. */
9304f876
CJW
4682 sp_adjust = cfun->machine->local_size
4683 + cfun->machine->out_args_size
e2286268
MC
4684 + cfun->machine->callee_saved_area_gpr_padding_bytes
4685 + cfun->machine->callee_saved_fpr_regs_size;
4686
4687 /* Restore fpu registers. */
4688 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4689 {
4690 /* Set $sp to callee saved fpr position, we need to restore
4691 fpr registers. */
4692 sp_adjust = sp_adjust
4693 - cfun->machine->callee_saved_area_gpr_padding_bytes
4694 - cfun->machine->callee_saved_fpr_regs_size;
4695
4696 nds32_emit_adjust_frame (stack_pointer_rtx,
4697 stack_pointer_rtx,
4698 sp_adjust);
4699
4700 /* Emit fpu load instruction, using [$sp + offset] restore
4701 fpu registers. */
4702 nds32_emit_v3pop_fpr_callee_saved (0);
4703 }
4704 else
4705 {
4706 /* sp_adjust value may be out of range of the addi instruction,
4707 create alternative add behavior with TA_REGNUM if necessary,
4708 using POSITIVE value to tell that we are increasing
4709 address. */
4710 nds32_emit_adjust_frame (stack_pointer_rtx,
4711 stack_pointer_rtx,
4712 sp_adjust);
4713 }
9304f876
CJW
4714 }
4715
e2286268
MC
4716 if (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)
4717 {
4718 /* We have fpr need to restore, so $sp is set on callee saved fpr
4719 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
4720 int fpr_space = cfun->machine->callee_saved_area_gpr_padding_bytes
4721 + cfun->machine->callee_saved_fpr_regs_size;
4722 nds32_emit_stack_v3pop (Rb, Re, fpr_space);
4723 }
4724 else
4725 {
4726 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4727 the pattern 'stack_v3pop' is implementad in nds32.md. */
4728 nds32_emit_stack_v3pop (Rb, Re, 0);
4729 }
9304f876 4730 }
aa2642ef
CJW
4731 /* Generate return instruction. */
4732 emit_jump_insn (gen_pop25return ());
9304f876
CJW
4733}
4734
03390cda
CJW
4735/* Return nonzero if this function is known to have a null epilogue.
4736 This allows the optimizer to omit jumps to jumps if no stack
4737 was created. */
4738int
4739nds32_can_use_return_insn (void)
4740{
e2286268
MC
4741 int sp_adjust;
4742
03390cda
CJW
4743 /* Prior to reloading, we can't tell how many registers must be saved.
4744 Thus we can not determine whether this function has null epilogue. */
4745 if (!reload_completed)
4746 return 0;
4747
e2286268
MC
4748 sp_adjust = cfun->machine->local_size
4749 + cfun->machine->out_args_size
4750 + cfun->machine->callee_saved_area_gpr_padding_bytes
4751 + cfun->machine->callee_saved_fpr_regs_size;
4752 if (!cfun->machine->fp_as_gp_p
4753 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
4754 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
4755 && !cfun->calls_alloca
4756 && NDS32_V3PUSH_AVAILABLE_P
4757 && !(TARGET_HARD_FLOAT
4758 && (cfun->machine->callee_saved_first_fpr_regno != SP_REGNUM)))
4759 return 1;
4760
03390cda
CJW
4761 /* If no stack was created, two conditions must be satisfied:
4762 1. This is a naked function.
8a498f99 4763 So there is no callee-saved, local size, or outgoing size.
03390cda 4764 2. This is NOT a variadic function.
8a498f99 4765 So there is no pushing arguement registers into the stack. */
03390cda
CJW
4766 return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0));
4767}
4768
9304f876
CJW
4769/* ------------------------------------------------------------------------ */
4770
4771/* Function to test 333-form for load/store instructions.
4772 This is auxiliary extern function for auxiliary macro in nds32.h.
4773 Because it is a little complicated, we use function instead of macro. */
4774bool
ef4bddc2 4775nds32_ls_333_p (rtx rt, rtx ra, rtx imm, machine_mode mode)
9304f876
CJW
4776{
4777 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
4778 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
4779 {
4780 if (GET_MODE_SIZE (mode) == 4)
4781 return satisfies_constraint_Iu05 (imm);
4782
4783 if (GET_MODE_SIZE (mode) == 2)
4784 return satisfies_constraint_Iu04 (imm);
4785
4786 if (GET_MODE_SIZE (mode) == 1)
4787 return satisfies_constraint_Iu03 (imm);
4788 }
4789
4790 return false;
4791}
4792
43fa41c1
CJW
4793/* Return alignment for the label. */
4794int
4795nds32_target_alignment (rtx_insn *label)
4796{
4797 rtx_insn *insn;
4798
4799 if (!NDS32_ALIGN_P ())
4800 return 0;
4801
4802 insn = next_active_insn (label);
4803
4804 /* Always align to 4 byte when first instruction after label is jump
4805 instruction since length for that might changed, so let's always align
4806 it for make sure we don't lose any perfomance here. */
4807 if (insn == 0
4808 || (get_attr_length (insn) == 2
4809 && !JUMP_P (insn) && !CALL_P (insn)))
4810 return 0;
4811 else
4812 return 2;
4813}
4814
e2286268
MC
4815bool
4816nds32_split_double_word_load_store_p(rtx *operands, bool load_p)
4817{
4818 rtx mem = load_p ? operands[1] : operands[0];
4819 /* Do split at split2 if -O0 or schedule 2 not enable. */
4820 if (optimize == 0 || !flag_schedule_insns_after_reload)
4821 return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem);
4822
4823 /* Split double word load store after copy propgation. */
4824 if (current_pass == NULL)
4825 return false;
4826
4827 const char *pass_name = current_pass->name;
4828 if (pass_name && ((strcmp (pass_name, "split4") == 0)
4829 || (strcmp (pass_name, "split5") == 0)))
4830 return !satisfies_constraint_Da (mem) || MEM_VOLATILE_P (mem);
4831
4832 return false;
4833}
4834
4835static bool
4836nds32_use_blocks_for_constant_p (machine_mode mode,
4837 const_rtx x ATTRIBUTE_UNUSED)
4838{
4839 if ((TARGET_FPU_SINGLE || TARGET_FPU_DOUBLE)
4840 && (mode == DFmode || mode == SFmode))
4841 return true;
4842 else
4843 return false;
4844}
9304f876 4845
9304f876
CJW
4846/* ------------------------------------------------------------------------ */
4847
4848/* PART 5: Initialize target hook structure and definitions. */
4849\f
4850/* Controlling the Compilation Driver. */
4851
4852\f
4853/* Run-time Target Specification. */
4854
4855\f
4856/* Defining Data Structures for Per-function Information. */
4857
4858\f
4859/* Storage Layout. */
4860
4861#undef TARGET_PROMOTE_FUNCTION_MODE
4862#define TARGET_PROMOTE_FUNCTION_MODE \
4863 default_promote_function_mode_always_promote
4864
5f2a98c3
CJW
4865#undef TARGET_EXPAND_TO_RTL_HOOK
4866#define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
4867
9304f876
CJW
4868\f
4869/* Layout of Source Language Data Types. */
4870
4871\f
4872/* Register Usage. */
4873
4874/* -- Basic Characteristics of Registers. */
4875
e2286268
MC
4876#undef TARGET_CONDITIONAL_REGISTER_USAGE
4877#define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
4878
9304f876
CJW
4879/* -- Order of Allocation of Registers. */
4880
4881/* -- How Values Fit in Registers. */
4882
e2286268
MC
4883#undef TARGET_HARD_REGNO_NREGS
4884#define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
4885
50256c75
CJW
4886#undef TARGET_HARD_REGNO_MODE_OK
4887#define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
4888
4889#undef TARGET_MODES_TIEABLE_P
4890#define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
4891
9304f876
CJW
4892/* -- Handling Leaf Functions. */
4893
4894/* -- Registers That Form a Stack. */
4895
4896\f
4897/* Register Classes. */
4898
4899#undef TARGET_CLASS_MAX_NREGS
4900#define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
4901
9304f876
CJW
4902#undef TARGET_REGISTER_PRIORITY
4903#define TARGET_REGISTER_PRIORITY nds32_register_priority
4904
e2286268
MC
4905#undef TARGET_CAN_CHANGE_MODE_CLASS
4906#define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
4907
9304f876
CJW
4908\f
4909/* Obsolete Macros for Defining Constraints. */
4910
4911\f
4912/* Stack Layout and Calling Conventions. */
4913
4914/* -- Basic Stack Layout. */
4915
4916/* -- Exception Handling Support. */
4917
4918/* -- Specifying How Stack Checking is Done. */
4919
4920/* -- Registers That Address the Stack Frame. */
4921
4922/* -- Eliminating Frame Pointer and Arg Pointer. */
4923
4924#undef TARGET_CAN_ELIMINATE
4925#define TARGET_CAN_ELIMINATE nds32_can_eliminate
4926
4927/* -- Passing Function Arguments on the Stack. */
4928
4929/* -- Passing Arguments in Registers. */
4930
4931#undef TARGET_FUNCTION_ARG
4932#define TARGET_FUNCTION_ARG nds32_function_arg
4933
d40f3c40
CJW
4934#undef TARGET_MUST_PASS_IN_STACK
4935#define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
4936
650fc469
CJW
4937#undef TARGET_ARG_PARTIAL_BYTES
4938#define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
4939
9304f876
CJW
4940#undef TARGET_FUNCTION_ARG_ADVANCE
4941#define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
4942
4943#undef TARGET_FUNCTION_ARG_BOUNDARY
4944#define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
4945
4946/* -- How Scalar Function Values Are Returned. */
4947
4948#undef TARGET_FUNCTION_VALUE
4949#define TARGET_FUNCTION_VALUE nds32_function_value
4950
4951#undef TARGET_LIBCALL_VALUE
4952#define TARGET_LIBCALL_VALUE nds32_libcall_value
4953
4954#undef TARGET_FUNCTION_VALUE_REGNO_P
4955#define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
4956
4957/* -- How Large Values Are Returned. */
4958
e2286268
MC
4959#undef TARGET_RETURN_IN_MEMORY
4960#define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
4961
9304f876
CJW
4962/* -- Caller-Saves Register Allocation. */
4963
4964/* -- Function Entry and Exit. */
4965
4966#undef TARGET_ASM_FUNCTION_PROLOGUE
4967#define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
4968
4969#undef TARGET_ASM_FUNCTION_END_PROLOGUE
4970#define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
4971
4972#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
4973#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
4974
4975#undef TARGET_ASM_FUNCTION_EPILOGUE
4976#define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
4977
4978#undef TARGET_ASM_OUTPUT_MI_THUNK
4979#define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
4980
4981#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
4982#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
4983
4984/* -- Generating Code for Profiling. */
4985
4986/* -- Permitting tail calls. */
4987
cc48a87f
CJW
4988#undef TARGET_FUNCTION_OK_FOR_SIBCALL
4989#define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
4990
9304f876
CJW
4991#undef TARGET_WARN_FUNC_RETURN
4992#define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
4993
4994/* Stack smashing protection. */
4995
4996\f
4997/* Implementing the Varargs Macros. */
4998
d4a6a4d9
CJW
4999#undef TARGET_SETUP_INCOMING_VARARGS
5000#define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5001
9304f876
CJW
5002#undef TARGET_STRICT_ARGUMENT_NAMING
5003#define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5004
5005\f
5006/* Trampolines for Nested Functions. */
5007
5008#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5009#define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5010
5011#undef TARGET_TRAMPOLINE_INIT
5012#define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5013
5014\f
5015/* Implicit Calls to Library Routines. */
5016
5017\f
5018/* Addressing Modes. */
5019
5020#undef TARGET_LEGITIMATE_ADDRESS_P
5021#define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5022
5023\f
5024/* Anchored Addresses. */
5025
5026\f
5027/* Condition Code Status. */
5028
5029/* -- Representation of condition codes using (cc0). */
5030
5031/* -- Representation of condition codes using registers. */
5032
5b6f2bf3
CJW
5033#undef TARGET_CANONICALIZE_COMPARISON
5034#define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5035
9304f876
CJW
5036/* -- Macros to control conditional execution. */
5037
5038\f
5039/* Describing Relative Costs of Operations. */
5040
5041#undef TARGET_REGISTER_MOVE_COST
5042#define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5043
5044#undef TARGET_MEMORY_MOVE_COST
5045#define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5046
5047#undef TARGET_RTX_COSTS
5048#define TARGET_RTX_COSTS nds32_rtx_costs
5049
5050#undef TARGET_ADDRESS_COST
5051#define TARGET_ADDRESS_COST nds32_address_cost
5052
5053\f
5054/* Adjusting the Instruction Scheduler. */
5055
5056\f
5057/* Dividing the Output into Sections (Texts, Data, . . . ). */
5058
511a41d7
CJW
5059#undef TARGET_ENCODE_SECTION_INFO
5060#define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5061
9304f876
CJW
5062\f
5063/* Position Independent Code. */
5064
5065\f
5066/* Defining the Output Assembler Language. */
5067
5068/* -- The Overall Framework of an Assembler File. */
5069
5070#undef TARGET_ASM_FILE_START
5071#define TARGET_ASM_FILE_START nds32_asm_file_start
5072#undef TARGET_ASM_FILE_END
5073#define TARGET_ASM_FILE_END nds32_asm_file_end
5074
5075/* -- Output of Data. */
5076
5077#undef TARGET_ASM_ALIGNED_HI_OP
5078#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5079
5080#undef TARGET_ASM_ALIGNED_SI_OP
5081#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5082
5083/* -- Output of Uninitialized Variables. */
5084
5085/* -- Output and Generation of Labels. */
5086
5087#undef TARGET_ASM_GLOBALIZE_LABEL
5088#define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5089
5090/* -- How Initialization Functions Are Handled. */
5091
5092/* -- Macros Controlling Initialization Routines. */
5093
5094/* -- Output of Assembler Instructions. */
5095
5096#undef TARGET_PRINT_OPERAND
5097#define TARGET_PRINT_OPERAND nds32_print_operand
5098#undef TARGET_PRINT_OPERAND_ADDRESS
5099#define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5100
5101/* -- Output of Dispatch Tables. */
5102
5103/* -- Assembler Commands for Exception Regions. */
5104
e2286268
MC
5105#undef TARGET_DWARF_REGISTER_SPAN
5106#define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5107
9304f876
CJW
5108/* -- Assembler Commands for Alignment. */
5109
5110\f
5111/* Controlling Debugging Information Format. */
5112
5113/* -- Macros Affecting All Debugging Formats. */
5114
5115/* -- Specific Options for DBX Output. */
5116
5117/* -- Open-Ended Hooks for DBX Format. */
5118
5119/* -- File Names in DBX Format. */
5120
180295ed 5121/* -- Macros for DWARF Output. */
9304f876
CJW
5122
5123/* -- Macros for VMS Debug Format. */
5124
5125\f
5126/* Cross Compilation and Floating Point. */
5127
5128\f
5129/* Mode Switching Instructions. */
5130
5131\f
5132/* Defining target-specific uses of __attribute__. */
5133
5134#undef TARGET_ATTRIBUTE_TABLE
5135#define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5136
5137#undef TARGET_MERGE_DECL_ATTRIBUTES
5138#define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5139
5140#undef TARGET_INSERT_ATTRIBUTES
5141#define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5142
5143#undef TARGET_OPTION_PRAGMA_PARSE
5144#define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5145
5146#undef TARGET_OPTION_OVERRIDE
5147#define TARGET_OPTION_OVERRIDE nds32_option_override
5148
5149\f
5150/* Emulating TLS. */
5151
5152\f
5153/* Defining coprocessor specifics for MIPS targets. */
5154
5155\f
5156/* Parameters for Precompiled Header Validity Checking. */
5157
5158\f
5159/* C++ ABI parameters. */
5160
5161\f
5162/* Adding support for named address spaces. */
5163
5164\f
5165/* Miscellaneous Parameters. */
5166
823835a9
CJW
5167#undef TARGET_MD_ASM_ADJUST
5168#define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5169
9304f876
CJW
5170#undef TARGET_INIT_BUILTINS
5171#define TARGET_INIT_BUILTINS nds32_init_builtins
5172
7a12ea32
MC
5173#undef TARGET_BUILTIN_DECL
5174#define TARGET_BUILTIN_DECL nds32_builtin_decl
5175
9304f876
CJW
5176#undef TARGET_EXPAND_BUILTIN
5177#define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5178
e2286268
MC
5179
5180#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5181#define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5182
9304f876
CJW
5183\f
5184/* ------------------------------------------------------------------------ */
5185
5186/* Initialize the GCC target structure. */
5187
5188struct gcc_target targetm = TARGET_INITIALIZER;
5189
5190/* ------------------------------------------------------------------------ */