Rebase.
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob2609a168e07f2b1c436f6bf357d2da04b00d53f4
1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2014 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "stor-layout.h"
29 #include "varasm.h"
30 #include "calls.h"
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h" /* Required by recog.h. */
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h" /* For DFA state_t. */
38 #include "insn-codes.h" /* For CODE_FOR_xxx. */
39 #include "reload.h" /* For push_reload(). */
40 #include "flags.h"
41 #include "function.h"
42 #include "expr.h"
43 #include "recog.h"
44 #include "diagnostic-core.h"
45 #include "df.h"
46 #include "tm_p.h"
47 #include "tm-constrs.h"
48 #include "optabs.h" /* For GEN_FCN. */
49 #include "target.h"
50 #include "target-def.h"
51 #include "langhooks.h" /* For add_builtin_function(). */
52 #include "ggc.h"
53 #include "builtins.h"
55 /* ------------------------------------------------------------------------ */
57 /* This file is divided into five parts:
59 PART 1: Auxiliary static variable definitions and
60 target hook static variable definitions.
62 PART 2: Auxiliary static function definitions.
64 PART 3: Implement target hook stuff definitions.
66 PART 4: Implemet extern function definitions,
67 the prototype is in nds32-protos.h.
69 PART 5: Initialize target hook structure and definitions. */
71 /* ------------------------------------------------------------------------ */
73 /* PART 1: Auxiliary static variable definitions and
74 target hook static variable definitions. */
76 /* Define intrinsic register names.
77 Please refer to nds32_intrinsic.h file, the index is corresponding to
78 'enum nds32_intrinsic_registers' data type values.
79 NOTE that the base value starting from 1024. */
80 static const char * const nds32_intrinsic_register_names[] =
82 "$PSW", "$IPSW", "$ITYPE", "$IPC"
85 /* Defining target-specific uses of __attribute__. */
86 static const struct attribute_spec nds32_attribute_table[] =
88 /* Syntax: { name, min_len, max_len, decl_required, type_required,
89 function_type_required, handler, affects_type_identity } */
91 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
92 { "interrupt", 1, 64, false, false, false, NULL, false },
93 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
94 { "exception", 1, 8, false, false, false, NULL, false },
95 /* Argument is user's interrupt numbers. The vector number is always 0. */
96 { "reset", 1, 1, false, false, false, NULL, false },
98 /* The attributes describing isr nested type. */
99 { "nested", 0, 0, false, false, false, NULL, false },
100 { "not_nested", 0, 0, false, false, false, NULL, false },
101 { "nested_ready", 0, 0, false, false, false, NULL, false },
103 /* The attributes describing isr register save scheme. */
104 { "save_all", 0, 0, false, false, false, NULL, false },
105 { "partial_save", 0, 0, false, false, false, NULL, false },
107 /* The attributes used by reset attribute. */
108 { "nmi", 1, 1, false, false, false, NULL, false },
109 { "warm", 1, 1, false, false, false, NULL, false },
111 /* The attribute telling no prologue/epilogue. */
112 { "naked", 0, 0, false, false, false, NULL, false },
114 /* The last attribute spec is set to be NULL. */
115 { NULL, 0, 0, false, false, false, NULL, false }
119 /* ------------------------------------------------------------------------ */
121 /* PART 2: Auxiliary static function definitions. */
123 /* Function to save and restore machine-specific function data. */
124 static struct machine_function *
125 nds32_init_machine_status (void)
127 struct machine_function *machine;
128 machine = ggc_cleared_alloc<machine_function> ();
130 /* Initially assume this function needs prologue/epilogue. */
131 machine->naked_p = 0;
133 /* Initially assume this function does NOT use fp_as_gp optimization. */
134 machine->fp_as_gp_p = 0;
136 return machine;
139 /* Function to compute stack frame size and
140 store into cfun->machine structure. */
141 static void
142 nds32_compute_stack_frame (void)
144 int r;
145 int block_size;
147 /* Because nds32_compute_stack_frame() will be called from different place,
148 everytime we enter this function, we have to assume this function
149 needs prologue/epilogue. */
150 cfun->machine->naked_p = 0;
152 /* Get variadic arguments size to prepare pretend arguments and
153 push them into stack at prologue.
154 Currently, we do not push variadic arguments by ourself.
155 We have GCC handle all the works.
156 The caller will push all corresponding nameless arguments into stack,
157 and the callee is able to retrieve them without problems.
158 These variables are still preserved in case one day
159 we would like caller passing arguments with registers. */
160 cfun->machine->va_args_size = 0;
161 cfun->machine->va_args_first_regno = SP_REGNUM;
162 cfun->machine->va_args_last_regno = SP_REGNUM;
164 /* Get local variables, incoming variables, and temporary variables size.
165 Note that we need to make sure it is 8-byte alignment because
166 there may be no padding bytes if we are using LRA. */
167 cfun->machine->local_size = NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
169 /* Get outgoing arguments size. */
170 cfun->machine->out_args_size = crtl->outgoing_args_size;
172 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
173 Check whether $fp is ever live. */
174 cfun->machine->fp_size = (df_regs_ever_live_p (FP_REGNUM)) ? 4 : 0;
176 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
177 Check whether we are using PIC code genration. */
178 cfun->machine->gp_size = (flag_pic) ? 4 : 0;
180 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
181 Check whether $lp is ever live. */
182 cfun->machine->lp_size = (df_regs_ever_live_p (LP_REGNUM)) ? 4 : 0;
184 /* Initially there is no padding bytes. */
185 cfun->machine->callee_saved_area_padding_bytes = 0;
187 /* Calculate the bytes of saving callee-saved registers on stack. */
188 cfun->machine->callee_saved_regs_size = 0;
189 cfun->machine->callee_saved_regs_first_regno = SP_REGNUM;
190 cfun->machine->callee_saved_regs_last_regno = SP_REGNUM;
191 /* Currently, there is no need to check $r28~$r31
192 because we will save them in another way. */
193 for (r = 0; r < 28; r++)
195 if (NDS32_REQUIRED_CALLEE_SAVED_P (r))
197 /* Mark the first required callee-saved register
198 (only need to set it once).
199 If first regno == SP_REGNUM, we can tell that
200 it is the first time to be here. */
201 if (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM)
202 cfun->machine->callee_saved_regs_first_regno = r;
203 /* Mark the last required callee-saved register. */
204 cfun->machine->callee_saved_regs_last_regno = r;
208 /* Check if this function can omit prologue/epilogue code fragment.
209 If there is 'naked' attribute in this function,
210 we can set 'naked_p' flag to indicate that
211 we do not have to generate prologue/epilogue.
212 Or, if all the following conditions succeed,
213 we can set this function 'naked_p' as well:
214 condition 1: first_regno == last_regno == SP_REGNUM,
215 which means we do not have to save
216 any callee-saved registers.
217 condition 2: Both $lp and $fp are NOT live in this function,
218 which means we do not need to save them.
219 condition 3: There is no local_size, which means
220 we do not need to adjust $sp. */
221 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
222 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
223 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
224 && !df_regs_ever_live_p (FP_REGNUM)
225 && !df_regs_ever_live_p (LP_REGNUM)
226 && cfun->machine->local_size == 0))
228 /* Set this function 'naked_p' and
229 other functions can check this flag. */
230 cfun->machine->naked_p = 1;
232 /* No need to save $fp, $gp, and $lp.
233 We should set these value to be zero
234 so that nds32_initial_elimination_offset() can work properly. */
235 cfun->machine->fp_size = 0;
236 cfun->machine->gp_size = 0;
237 cfun->machine->lp_size = 0;
239 /* If stack usage computation is required,
240 we need to provide the static stack size. */
241 if (flag_stack_usage_info)
242 current_function_static_stack_size = 0;
244 /* No need to do following adjustment, return immediately. */
245 return;
248 /* Adjustment for v3push instructions:
249 If we are using v3push (push25/pop25) instructions,
250 we need to make sure Rb is $r6 and Re is
251 located on $r6, $r8, $r10, or $r14.
252 Some results above will be discarded and recomputed.
253 Note that it is only available under V3/V3M ISA. */
254 if (TARGET_V3PUSH)
256 /* Recompute:
257 cfun->machine->fp_size
258 cfun->machine->gp_size
259 cfun->machine->lp_size
260 cfun->machine->callee_saved_regs_first_regno
261 cfun->machine->callee_saved_regs_last_regno */
263 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
264 cfun->machine->fp_size = 4;
265 cfun->machine->gp_size = 4;
266 cfun->machine->lp_size = 4;
268 /* Remember to set Rb = $r6. */
269 cfun->machine->callee_saved_regs_first_regno = 6;
271 if (cfun->machine->callee_saved_regs_last_regno <= 6)
273 /* Re = $r6 */
274 cfun->machine->callee_saved_regs_last_regno = 6;
276 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
278 /* Re = $r8 */
279 cfun->machine->callee_saved_regs_last_regno = 8;
281 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
283 /* Re = $r10 */
284 cfun->machine->callee_saved_regs_last_regno = 10;
286 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
288 /* Re = $r14 */
289 cfun->machine->callee_saved_regs_last_regno = 14;
291 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
293 /* If last_regno is SP_REGNUM, which means
294 it is never changed, so set it to Re = $r6. */
295 cfun->machine->callee_saved_regs_last_regno = 6;
297 else
299 /* The program flow should not go here. */
300 gcc_unreachable ();
304 /* We have correctly set callee_saved_regs_first_regno
305 and callee_saved_regs_last_regno.
306 Initially, the callee_saved_regs_size is supposed to be 0.
307 As long as callee_saved_regs_last_regno is not SP_REGNUM,
308 we can update callee_saved_regs_size with new size. */
309 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
311 /* Compute pushed size of callee-saved registers. */
312 cfun->machine->callee_saved_regs_size
313 = 4 * (cfun->machine->callee_saved_regs_last_regno
314 - cfun->machine->callee_saved_regs_first_regno
315 + 1);
318 /* Important: We need to make sure that
319 (va_args_size + fp_size + gp_size
320 + lp_size + callee_saved_regs_size)
321 is 8-byte alignment.
322 If it is not, calculate the padding bytes. */
323 block_size = cfun->machine->va_args_size
324 + cfun->machine->fp_size
325 + cfun->machine->gp_size
326 + cfun->machine->lp_size
327 + cfun->machine->callee_saved_regs_size;
328 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
330 cfun->machine->callee_saved_area_padding_bytes
331 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
334 /* If stack usage computation is required,
335 we need to provide the static stack size. */
336 if (flag_stack_usage_info)
338 current_function_static_stack_size
339 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
340 + cfun->machine->local_size
341 + cfun->machine->out_args_size;
345 /* Function to create a parallel rtx pattern
346 which presents stack push multiple behavior.
347 The overall concept are:
348 "push registers to memory",
349 "adjust stack pointer". */
350 static rtx
351 nds32_gen_stack_push_multiple (rtx Rb, rtx Re,
352 rtx En4 ATTRIBUTE_UNUSED)
354 int regno;
355 int extra_count;
356 int num_use_regs;
357 int par_index;
358 int offset;
360 rtx reg;
361 rtx mem;
362 rtx push_rtx;
363 rtx adjust_sp_rtx;
364 rtx parallel_insn;
366 /* We need to provide a customized rtx which contains
367 necessary information for data analysis,
368 so we create a parallel rtx like this:
369 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
370 (reg:SI Rb))
371 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
372 (reg:SI Rb+1))
374 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
375 (reg:SI Re))
376 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
377 (reg:SI FP_REGNUM))
378 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
379 (reg:SI GP_REGNUM))
380 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
381 (reg:SI LP_REGNUM))
382 (set (reg:SI SP_REGNUM)
383 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
385 /* Calculate the number of registers that will be pushed. */
386 extra_count = 0;
387 if (cfun->machine->fp_size)
388 extra_count++;
389 if (cfun->machine->gp_size)
390 extra_count++;
391 if (cfun->machine->lp_size)
392 extra_count++;
393 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
394 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
395 num_use_regs = extra_count;
396 else
397 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
399 /* In addition to used registers,
400 we need one more space for (set sp sp-x) rtx. */
401 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
402 rtvec_alloc (num_use_regs + 1));
403 par_index = 0;
405 /* Initialize offset and start to create push behavior. */
406 offset = -(num_use_regs * 4);
408 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
409 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
411 /* Rb and Re may be SP_REGNUM.
412 We need to break this loop immediately. */
413 if (regno == SP_REGNUM)
414 break;
416 reg = gen_rtx_REG (SImode, regno);
417 mem = gen_frame_mem (SImode, plus_constant (Pmode,
418 stack_pointer_rtx,
419 offset));
420 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
421 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
422 RTX_FRAME_RELATED_P (push_rtx) = 1;
423 offset = offset + 4;
424 par_index++;
427 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
428 if (cfun->machine->fp_size)
430 reg = gen_rtx_REG (SImode, FP_REGNUM);
431 mem = gen_frame_mem (SImode, plus_constant (Pmode,
432 stack_pointer_rtx,
433 offset));
434 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
435 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
436 RTX_FRAME_RELATED_P (push_rtx) = 1;
437 offset = offset + 4;
438 par_index++;
440 if (cfun->machine->gp_size)
442 reg = gen_rtx_REG (SImode, GP_REGNUM);
443 mem = gen_frame_mem (SImode, plus_constant (Pmode,
444 stack_pointer_rtx,
445 offset));
446 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
447 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
448 RTX_FRAME_RELATED_P (push_rtx) = 1;
449 offset = offset + 4;
450 par_index++;
452 if (cfun->machine->lp_size)
454 reg = gen_rtx_REG (SImode, LP_REGNUM);
455 mem = gen_frame_mem (SImode, plus_constant (Pmode,
456 stack_pointer_rtx,
457 offset));
458 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
459 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
460 RTX_FRAME_RELATED_P (push_rtx) = 1;
461 offset = offset + 4;
462 par_index++;
465 /* Create (set sp sp-x). */
467 /* We need to re-calculate the offset value again for adjustment. */
468 offset = -(num_use_regs * 4);
469 adjust_sp_rtx
470 = gen_rtx_SET (VOIDmode,
471 stack_pointer_rtx,
472 plus_constant (Pmode, stack_pointer_rtx, offset));
473 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
474 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
476 return parallel_insn;
479 /* Function to create a parallel rtx pattern
480 which presents stack pop multiple behavior.
481 The overall concept are:
482 "pop registers from memory",
483 "adjust stack pointer". */
484 static rtx
485 nds32_gen_stack_pop_multiple (rtx Rb, rtx Re,
486 rtx En4 ATTRIBUTE_UNUSED)
488 int regno;
489 int extra_count;
490 int num_use_regs;
491 int par_index;
492 int offset;
494 rtx reg;
495 rtx mem;
496 rtx pop_rtx;
497 rtx adjust_sp_rtx;
498 rtx parallel_insn;
500 /* We need to provide a customized rtx which contains
501 necessary information for data analysis,
502 so we create a parallel rtx like this:
503 (parallel [(set (reg:SI Rb)
504 (mem (reg:SI SP_REGNUM)))
505 (set (reg:SI Rb+1)
506 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
508 (set (reg:SI Re)
509 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
510 (set (reg:SI FP_REGNUM)
511 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
512 (set (reg:SI GP_REGNUM)
513 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
514 (set (reg:SI LP_REGNUM)
515 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
516 (set (reg:SI SP_REGNUM)
517 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
519 /* Calculate the number of registers that will be poped. */
520 extra_count = 0;
521 if (cfun->machine->fp_size)
522 extra_count++;
523 if (cfun->machine->gp_size)
524 extra_count++;
525 if (cfun->machine->lp_size)
526 extra_count++;
527 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
528 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
529 num_use_regs = extra_count;
530 else
531 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
533 /* In addition to used registers,
534 we need one more space for (set sp sp+x) rtx. */
535 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
536 rtvec_alloc (num_use_regs + 1));
537 par_index = 0;
539 /* Initialize offset and start to create pop behavior. */
540 offset = 0;
542 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
543 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
545 /* Rb and Re may be SP_REGNUM.
546 We need to break this loop immediately. */
547 if (regno == SP_REGNUM)
548 break;
550 reg = gen_rtx_REG (SImode, regno);
551 mem = gen_frame_mem (SImode, plus_constant (Pmode,
552 stack_pointer_rtx,
553 offset));
554 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
555 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
556 RTX_FRAME_RELATED_P (pop_rtx) = 1;
557 offset = offset + 4;
558 par_index++;
561 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
562 if (cfun->machine->fp_size)
564 reg = gen_rtx_REG (SImode, FP_REGNUM);
565 mem = gen_frame_mem (SImode, plus_constant (Pmode,
566 stack_pointer_rtx,
567 offset));
568 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
569 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
570 RTX_FRAME_RELATED_P (pop_rtx) = 1;
571 offset = offset + 4;
572 par_index++;
574 if (cfun->machine->gp_size)
576 reg = gen_rtx_REG (SImode, GP_REGNUM);
577 mem = gen_frame_mem (SImode, plus_constant (Pmode,
578 stack_pointer_rtx,
579 offset));
580 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
581 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
582 RTX_FRAME_RELATED_P (pop_rtx) = 1;
583 offset = offset + 4;
584 par_index++;
586 if (cfun->machine->lp_size)
588 reg = gen_rtx_REG (SImode, LP_REGNUM);
589 mem = gen_frame_mem (SImode, plus_constant (Pmode,
590 stack_pointer_rtx,
591 offset));
592 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
593 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
594 RTX_FRAME_RELATED_P (pop_rtx) = 1;
595 offset = offset + 4;
596 par_index++;
599 /* Create (set sp sp+x). */
601 /* The offset value is already in place. No need to re-calculate it. */
602 adjust_sp_rtx
603 = gen_rtx_SET (VOIDmode,
604 stack_pointer_rtx,
605 plus_constant (Pmode, stack_pointer_rtx, offset));
606 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
607 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
609 return parallel_insn;
612 /* Function to create a parallel rtx pattern
613 which presents stack v3push behavior.
614 The overall concept are:
615 "push registers to memory",
616 "adjust stack pointer". */
617 static rtx
618 nds32_gen_stack_v3push (rtx Rb,
619 rtx Re,
620 rtx En4 ATTRIBUTE_UNUSED,
621 rtx imm8u)
623 int regno;
624 int num_use_regs;
625 int par_index;
626 int offset;
628 rtx reg;
629 rtx mem;
630 rtx push_rtx;
631 rtx adjust_sp_rtx;
632 rtx parallel_insn;
634 /* We need to provide a customized rtx which contains
635 necessary information for data analysis,
636 so we create a parallel rtx like this:
637 (parallel [
638 (set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
639 (reg:SI Rb))
640 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
641 (reg:SI Rb+1))
643 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
644 (reg:SI Re))
645 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
646 (reg:SI FP_REGNUM))
647 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
648 (reg:SI GP_REGNUM))
649 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
650 (reg:SI LP_REGNUM))
651 (set (reg:SI SP_REGNUM)
652 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
654 /* Calculate the number of registers that will be pushed.
655 Since $fp, $gp, and $lp is always pushed with v3push instruction,
656 we need to count these three registers.
657 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
658 So there is no need to worry about Rb=Re=SP_REGNUM case. */
659 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
661 /* In addition to used registers,
662 we need one more space for (set sp sp-x-imm8u) rtx. */
663 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
664 rtvec_alloc (num_use_regs + 1));
665 par_index = 0;
667 /* Initialize offset and start to create push behavior. */
668 offset = -(num_use_regs * 4);
670 /* Create (set mem regX) from Rb, Rb+1 up to Re.
671 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
672 So there is no need to worry about Rb=Re=SP_REGNUM case. */
673 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
675 reg = gen_rtx_REG (SImode, regno);
676 mem = gen_frame_mem (SImode, plus_constant (Pmode,
677 stack_pointer_rtx,
678 offset));
679 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
680 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
681 RTX_FRAME_RELATED_P (push_rtx) = 1;
682 offset = offset + 4;
683 par_index++;
686 /* Create (set mem fp). */
687 reg = gen_rtx_REG (SImode, FP_REGNUM);
688 mem = gen_frame_mem (SImode, plus_constant (Pmode,
689 stack_pointer_rtx,
690 offset));
691 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
692 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
693 RTX_FRAME_RELATED_P (push_rtx) = 1;
694 offset = offset + 4;
695 par_index++;
696 /* Create (set mem gp). */
697 reg = gen_rtx_REG (SImode, GP_REGNUM);
698 mem = gen_frame_mem (SImode, plus_constant (Pmode,
699 stack_pointer_rtx,
700 offset));
701 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
702 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
703 RTX_FRAME_RELATED_P (push_rtx) = 1;
704 offset = offset + 4;
705 par_index++;
706 /* Create (set mem lp). */
707 reg = gen_rtx_REG (SImode, LP_REGNUM);
708 mem = gen_frame_mem (SImode, plus_constant (Pmode,
709 stack_pointer_rtx,
710 offset));
711 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
712 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
713 RTX_FRAME_RELATED_P (push_rtx) = 1;
714 offset = offset + 4;
715 par_index++;
717 /* Create (set sp sp-x-imm8u). */
719 /* We need to re-calculate the offset value again for adjustment. */
720 offset = -(num_use_regs * 4);
721 adjust_sp_rtx
722 = gen_rtx_SET (VOIDmode,
723 stack_pointer_rtx,
724 plus_constant (Pmode,
725 stack_pointer_rtx,
726 offset - INTVAL (imm8u)));
727 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
728 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
730 return parallel_insn;
733 /* Function to create a parallel rtx pattern
734 which presents stack v3pop behavior.
735 The overall concept are:
736 "pop registers from memory",
737 "adjust stack pointer". */
738 static rtx
739 nds32_gen_stack_v3pop (rtx Rb,
740 rtx Re,
741 rtx En4 ATTRIBUTE_UNUSED,
742 rtx imm8u)
744 int regno;
745 int num_use_regs;
746 int par_index;
747 int offset;
749 rtx reg;
750 rtx mem;
751 rtx pop_rtx;
752 rtx adjust_sp_rtx;
753 rtx parallel_insn;
755 /* We need to provide a customized rtx which contains
756 necessary information for data analysis,
757 so we create a parallel rtx like this:
758 (parallel [(set (reg:SI Rb)
759 (mem (reg:SI SP_REGNUM)))
760 (set (reg:SI Rb+1)
761 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
763 (set (reg:SI Re)
764 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
765 (set (reg:SI FP_REGNUM)
766 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
767 (set (reg:SI GP_REGNUM)
768 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
769 (set (reg:SI LP_REGNUM)
770 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
771 (set (reg:SI SP_REGNUM)
772 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
774 /* Calculate the number of registers that will be poped.
775 Since $fp, $gp, and $lp is always poped with v3pop instruction,
776 we need to count these three registers.
777 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
778 So there is no need to worry about Rb=Re=SP_REGNUM case. */
779 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
781 /* In addition to used registers,
782 we need one more space for (set sp sp+x+imm8u) rtx. */
783 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
784 rtvec_alloc (num_use_regs + 1));
785 par_index = 0;
787 /* Initialize offset and start to create pop behavior. */
788 offset = 0;
790 /* Create (set regX mem) from Rb, Rb+1 up to Re.
791 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
792 So there is no need to worry about Rb=Re=SP_REGNUM case. */
793 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
795 reg = gen_rtx_REG (SImode, regno);
796 mem = gen_frame_mem (SImode, plus_constant (Pmode,
797 stack_pointer_rtx,
798 offset));
799 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
800 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
801 RTX_FRAME_RELATED_P (pop_rtx) = 1;
802 offset = offset + 4;
803 par_index++;
806 /* Create (set fp mem). */
807 reg = gen_rtx_REG (SImode, FP_REGNUM);
808 mem = gen_frame_mem (SImode, plus_constant (Pmode,
809 stack_pointer_rtx,
810 offset));
811 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
812 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
813 RTX_FRAME_RELATED_P (pop_rtx) = 1;
814 offset = offset + 4;
815 par_index++;
816 /* Create (set gp mem). */
817 reg = gen_rtx_REG (SImode, GP_REGNUM);
818 mem = gen_frame_mem (SImode, plus_constant (Pmode,
819 stack_pointer_rtx,
820 offset));
821 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
822 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
823 RTX_FRAME_RELATED_P (pop_rtx) = 1;
824 offset = offset + 4;
825 par_index++;
826 /* Create (set lp mem ). */
827 reg = gen_rtx_REG (SImode, LP_REGNUM);
828 mem = gen_frame_mem (SImode, plus_constant (Pmode,
829 stack_pointer_rtx,
830 offset));
831 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
832 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
833 RTX_FRAME_RELATED_P (pop_rtx) = 1;
834 offset = offset + 4;
835 par_index++;
837 /* Create (set sp sp+x+imm8u). */
839 /* The offset value is already in place. No need to re-calculate it. */
840 adjust_sp_rtx
841 = gen_rtx_SET (VOIDmode,
842 stack_pointer_rtx,
843 plus_constant (Pmode,
844 stack_pointer_rtx,
845 offset + INTVAL (imm8u)));
846 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
847 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
849 return parallel_insn;
852 /* Function that may creates more instructions
853 for large value on adjusting stack pointer.
855 In nds32 target, 'addi' can be used for stack pointer
856 adjustment in prologue/epilogue stage.
857 However, sometimes there are too many local variables so that
858 the adjustment value is not able to be fit in the 'addi' instruction.
859 One solution is to move value into a register
860 and then use 'add' instruction.
861 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
862 Also, we need to return zero for sp adjustment so that
863 proglogue/epilogue knows there is no need to create 'addi' instruction. */
864 static int
865 nds32_force_addi_stack_int (int full_value)
867 int adjust_value;
869 rtx tmp_reg;
870 rtx sp_adjust_insn;
872 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
874 /* The value is not able to fit in single addi instruction.
875 Create more instructions of moving value into a register
876 and then add stack pointer with it. */
878 /* $r15 is going to be temporary register to hold the value. */
879 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
881 /* Create one more instruction to move value
882 into the temporary register. */
883 emit_move_insn (tmp_reg, GEN_INT (full_value));
885 /* Create new 'add' rtx. */
886 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
887 stack_pointer_rtx,
888 tmp_reg);
889 /* Emit rtx into insn list and receive its transformed insn rtx. */
890 sp_adjust_insn = emit_insn (sp_adjust_insn);
892 /* At prologue, we need to tell GCC that this is frame related insn,
893 so that we can consider this instruction to output debug information.
894 If full_value is NEGATIVE, it means this function
895 is invoked by expand_prologue. */
896 if (full_value < 0)
898 /* Because (tmp_reg <- full_value) may be split into two
899 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
900 We need to construct another (sp <- sp + full_value)
901 and then insert it into sp_adjust_insn's reg note to
902 represent a frame related expression.
903 GCC knows how to refer it and output debug information. */
905 rtx plus_rtx;
906 rtx set_rtx;
908 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
909 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
910 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
912 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
915 /* We have used alternative way to adjust stack pointer value.
916 Return zero so that prologue/epilogue
917 will not generate other instructions. */
918 return 0;
920 else
922 /* The value is able to fit in addi instruction.
923 However, remember to make it to be positive value
924 because we want to return 'adjustment' result. */
925 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
927 return adjust_value;
931 /* Return true if MODE/TYPE need double word alignment. */
932 static bool
933 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
935 unsigned int align;
937 /* Pick up the alignment according to the mode or type. */
938 align = NDS32_MODE_TYPE_ALIGN (mode, type);
940 return (align > PARM_BOUNDARY);
943 /* Return true if FUNC is a naked function. */
944 static bool
945 nds32_naked_function_p (tree func)
947 tree t;
949 if (TREE_CODE (func) != FUNCTION_DECL)
950 abort ();
952 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
954 return (t != NULL_TREE);
957 /* Function that check if 'X' is a valid address register.
958 The variable 'STRICT' is very important to
959 make decision for register number.
961 STRICT : true
962 => We are in reload pass or after reload pass.
963 The register number should be strictly limited in general registers.
965 STRICT : false
966 => Before reload pass, we are free to use any register number. */
967 static bool
968 nds32_address_register_rtx_p (rtx x, bool strict)
970 int regno;
972 if (GET_CODE (x) != REG)
973 return false;
975 regno = REGNO (x);
977 if (strict)
978 return REGNO_OK_FOR_BASE_P (regno);
979 else
980 return true;
983 /* Function that check if 'INDEX' is valid to be a index rtx for address.
985 OUTER_MODE : Machine mode of outer address rtx.
986 INDEX : Check if this rtx is valid to be a index for address.
987 STRICT : If it is true, we are in reload pass or after reload pass. */
988 static bool
989 nds32_legitimate_index_p (enum machine_mode outer_mode,
990 rtx index,
991 bool strict)
993 int regno;
994 rtx op0;
995 rtx op1;
997 switch (GET_CODE (index))
999 case REG:
1000 regno = REGNO (index);
1001 /* If we are in reload pass or after reload pass,
1002 we need to limit it to general register. */
1003 if (strict)
1004 return REGNO_OK_FOR_INDEX_P (regno);
1005 else
1006 return true;
1008 case CONST_INT:
1009 /* The alignment of the integer value is determined by 'outer_mode'. */
1010 if (GET_MODE_SIZE (outer_mode) == 1)
1012 /* Further check if the value is legal for the 'outer_mode'. */
1013 if (!satisfies_constraint_Is15 (index))
1014 return false;
1016 /* Pass all test, the value is valid, return true. */
1017 return true;
1019 if (GET_MODE_SIZE (outer_mode) == 2
1020 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1022 /* Further check if the value is legal for the 'outer_mode'. */
1023 if (!satisfies_constraint_Is16 (index))
1024 return false;
1026 /* Pass all test, the value is valid, return true. */
1027 return true;
1029 if (GET_MODE_SIZE (outer_mode) == 4
1030 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1032 /* Further check if the value is legal for the 'outer_mode'. */
1033 if (!satisfies_constraint_Is17 (index))
1034 return false;
1036 /* Pass all test, the value is valid, return true. */
1037 return true;
1039 if (GET_MODE_SIZE (outer_mode) == 8
1040 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1042 /* Further check if the value is legal for the 'outer_mode'. */
1043 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1044 SImode)))
1045 return false;
1047 /* Pass all test, the value is valid, return true. */
1048 return true;
1051 return false;
1053 case MULT:
1054 op0 = XEXP (index, 0);
1055 op1 = XEXP (index, 1);
1057 if (REG_P (op0) && CONST_INT_P (op1))
1059 int multiplier;
1060 multiplier = INTVAL (op1);
1062 /* We only allow (mult reg const_int_1)
1063 or (mult reg const_int_2) or (mult reg const_int_4). */
1064 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1065 return false;
1067 regno = REGNO (op0);
1068 /* Limit it in general registers if we are
1069 in reload pass or after reload pass. */
1070 if(strict)
1071 return REGNO_OK_FOR_INDEX_P (regno);
1072 else
1073 return true;
1076 return false;
1078 case ASHIFT:
1079 op0 = XEXP (index, 0);
1080 op1 = XEXP (index, 1);
1082 if (REG_P (op0) && CONST_INT_P (op1))
1084 int sv;
1085 /* op1 is already the sv value for use to do left shift. */
1086 sv = INTVAL (op1);
1088 /* We only allow (ashift reg const_int_0)
1089 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1090 if (sv != 0 && sv != 1 && sv !=2)
1091 return false;
1093 regno = REGNO (op0);
1094 /* Limit it in general registers if we are
1095 in reload pass or after reload pass. */
1096 if(strict)
1097 return REGNO_OK_FOR_INDEX_P (regno);
1098 else
1099 return true;
1102 return false;
1104 default:
1105 return false;
1109 /* ------------------------------------------------------------------------ */
1111 /* PART 3: Implement target hook stuff definitions. */
1113 /* Register Classes. */
1115 static unsigned char
1116 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1117 enum machine_mode mode)
1119 /* Return the maximum number of consecutive registers
1120 needed to represent "mode" in a register of "rclass". */
1121 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1124 static int
1125 nds32_register_priority (int hard_regno)
1127 /* Encourage to use r0-r7 for LRA when optimize for size. */
1128 if (optimize_size && hard_regno < 8)
1129 return 4;
1130 return 3;
1134 /* Stack Layout and Calling Conventions. */
1136 /* There are three kinds of pointer concepts using in GCC compiler:
1138 frame pointer: A pointer to the first location of local variables.
1139 stack pointer: A pointer to the top of a stack frame.
1140 argument pointer: A pointer to the incoming arguments.
1142 In nds32 target calling convention, we are using 8-byte alignment.
1143 Besides, we would like to have each stack frame of a function includes:
1145 [Block A]
1146 1. previous hard frame pointer
1147 2. return address
1148 3. callee-saved registers
1149 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1150 and save it at
1151 cfun->machine->callee_saved_area_padding_bytes)
1153 [Block B]
1154 1. local variables
1155 2. spilling location
1156 3. <padding bytes> (it will be calculated by GCC itself)
1157 4. incoming arguments
1158 5. <padding bytes> (it will be calculated by GCC itself)
1160 [Block C]
1161 1. <padding bytes> (it will be calculated by GCC itself)
1162 2. outgoing arguments
1164 We 'wrap' these blocks together with
1165 hard frame pointer ($r28) and stack pointer ($r31).
1166 By applying the basic frame/stack/argument pointers concept,
1167 the layout of a stack frame shoule be like this:
1170 old stack pointer -> ----
1171 | | \
1172 | | saved arguments for
1173 | | vararg functions
1174 | | /
1175 hard frame pointer -> --
1176 & argument pointer | | \
1177 | | previous hardware frame pointer
1178 | | return address
1179 | | callee-saved registers
1180 | | /
1181 frame pointer -> --
1182 | | \
1183 | | local variables
1184 | | and incoming arguments
1185 | | /
1187 | | \
1188 | | outgoing
1189 | | arguments
1190 | | /
1191 stack pointer -> ----
1193 $SFP and $AP are used to represent frame pointer and arguments pointer,
1194 which will be both eliminated as hard frame pointer. */
1196 /* -- Eliminating Frame Pointer and Arg Pointer. */
1198 static bool
1199 nds32_can_eliminate (const int from_reg, const int to_reg)
1201 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1202 return true;
1204 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1205 return true;
1207 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1208 return true;
1210 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1211 return true;
1213 return false;
1216 /* -- Passing Arguments in Registers. */
1218 static rtx
1219 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1220 const_tree type, bool named)
1222 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1224 /* The last time this hook is called,
1225 it is called with MODE == VOIDmode. */
1226 if (mode == VOIDmode)
1227 return NULL_RTX;
1229 /* For nameless arguments, they are passed on the stack. */
1230 if (!named)
1231 return NULL_RTX;
1233 /* If there are still registers available, return it. */
1234 if (NDS32_ARG_PASS_IN_REG_P (cum->reg_offset, mode, type))
1236 /* Pick up the next available register number. */
1237 unsigned int regno;
1239 regno = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type);
1240 return gen_rtx_REG (mode, regno);
1242 else
1244 /* No register available, return NULL_RTX.
1245 The compiler will use stack to pass argument instead. */
1246 return NULL_RTX;
1250 static void
1251 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1252 const_tree type, bool named)
1254 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1256 /* Advance next register for use.
1257 Only named argument could be advanced. */
1258 if (named)
1260 cum->reg_offset
1261 = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type)
1262 - NDS32_GPR_ARG_FIRST_REGNUM
1263 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1267 static unsigned int
1268 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1270 return (nds32_needs_double_word_align (mode, type)
1271 ? NDS32_DOUBLE_WORD_ALIGNMENT
1272 : PARM_BOUNDARY);
1275 /* -- How Scalar Function Values Are Returned. */
1277 static rtx
1278 nds32_function_value (const_tree ret_type,
1279 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1280 bool outgoing ATTRIBUTE_UNUSED)
1282 enum machine_mode mode;
1283 int unsignedp;
1285 mode = TYPE_MODE (ret_type);
1286 unsignedp = TYPE_UNSIGNED (ret_type);
1288 mode = promote_mode (ret_type, mode, &unsignedp);
1290 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1293 static rtx
1294 nds32_libcall_value (enum machine_mode mode,
1295 const_rtx fun ATTRIBUTE_UNUSED)
1297 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1300 static bool
1301 nds32_function_value_regno_p (const unsigned int regno)
1303 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1306 /* -- Function Entry and Exit. */
1308 /* The content produced from this function
1309 will be placed before prologue body. */
1310 static void
1311 nds32_asm_function_prologue (FILE *file,
1312 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1314 int r;
1315 const char *func_name;
1316 tree attrs;
1317 tree name;
1319 /* All stack frame information is supposed to be
1320 already computed when expanding prologue.
1321 The result is in cfun->machine.
1322 DO NOT call nds32_compute_stack_frame() here
1323 because it may corrupt the essential information. */
1325 fprintf (file, "\t! BEGIN PROLOGUE\n");
1326 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1327 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1328 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1329 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1331 /* Use df_regs_ever_live_p() to detect if the register
1332 is ever used in the current function. */
1333 fprintf (file, "\t! registers ever_live: ");
1334 for (r = 0; r < 32; r++)
1336 if (df_regs_ever_live_p (r))
1337 fprintf (file, "%s, ", reg_names[r]);
1339 fputc ('\n', file);
1341 /* Display the attributes of this function. */
1342 fprintf (file, "\t! function attributes: ");
1343 /* Get the attributes tree list.
1344 Note that GCC builds attributes list with reverse order. */
1345 attrs = DECL_ATTRIBUTES (current_function_decl);
1347 /* If there is no any attribute, print out "None". */
1348 if (!attrs)
1349 fprintf (file, "None");
1351 /* If there are some attributes, try if we need to
1352 construct isr vector information. */
1353 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1354 nds32_construct_isr_vectors_information (attrs, func_name);
1356 /* Display all attributes of this function. */
1357 while (attrs)
1359 name = TREE_PURPOSE (attrs);
1360 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1362 /* Pick up the next attribute. */
1363 attrs = TREE_CHAIN (attrs);
1365 fputc ('\n', file);
1368 /* After rtl prologue has been expanded, this function is used. */
1369 static void
1370 nds32_asm_function_end_prologue (FILE *file)
1372 fprintf (file, "\t! END PROLOGUE\n");
1374 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1375 we can generate special directive: ".omit_fp_begin"
1376 to guide linker doing fp-as-gp optimization.
1377 However, for a naked function, which means
1378 it should not have prologue/epilogue,
1379 using fp-as-gp still requires saving $fp by push/pop behavior and
1380 there is no benefit to use fp-as-gp on such small function.
1381 So we need to make sure this function is NOT naked as well. */
1382 if (!frame_pointer_needed
1383 && !cfun->machine->naked_p
1384 && cfun->machine->fp_as_gp_p)
1386 fprintf (file, "\t! ----------------------------------------\n");
1387 fprintf (file, "\t! Guide linker to do "
1388 "link time optimization: fp-as-gp\n");
1389 fprintf (file, "\t! We add one more instruction to "
1390 "initialize $fp near to $gp location.\n");
1391 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1392 fprintf (file, "\t! this extra instruction should be "
1393 "eliminated at link stage.\n");
1394 fprintf (file, "\t.omit_fp_begin\n");
1395 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1396 fprintf (file, "\t! ----------------------------------------\n");
1400 /* Before rtl epilogue has been expanded, this function is used. */
1401 static void
1402 nds32_asm_function_begin_epilogue (FILE *file)
1404 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1405 we can generate special directive: ".omit_fp_end"
1406 to claim fp-as-gp optimization range.
1407 However, for a naked function,
1408 which means it should not have prologue/epilogue,
1409 using fp-as-gp still requires saving $fp by push/pop behavior and
1410 there is no benefit to use fp-as-gp on such small function.
1411 So we need to make sure this function is NOT naked as well. */
1412 if (!frame_pointer_needed
1413 && !cfun->machine->naked_p
1414 && cfun->machine->fp_as_gp_p)
1416 fprintf (file, "\t! ----------------------------------------\n");
1417 fprintf (file, "\t! Claim the range of fp-as-gp "
1418 "link time optimization\n");
1419 fprintf (file, "\t.omit_fp_end\n");
1420 fprintf (file, "\t! ----------------------------------------\n");
1423 fprintf (file, "\t! BEGIN EPILOGUE\n");
1426 /* The content produced from this function
1427 will be placed after epilogue body. */
1428 static void
1429 nds32_asm_function_epilogue (FILE *file,
1430 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1432 fprintf (file, "\t! END EPILOGUE\n");
1435 static void
1436 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1437 HOST_WIDE_INT delta,
1438 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1439 tree function)
1441 int this_regno;
1443 /* Make sure unwind info is emitted for the thunk if needed. */
1444 final_start_function (emit_barrier (), file, 1);
1446 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1448 : 0);
1450 if (delta != 0)
1452 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1454 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1455 this_regno, this_regno, delta);
1457 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1459 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1460 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1462 else
1464 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1465 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1466 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1470 fprintf (file, "\tb\t");
1471 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1472 fprintf (file, "\n");
1474 final_end_function ();
1477 /* -- Permitting tail calls. */
1479 /* Determine whether we need to enable warning for function return check. */
1480 static bool
1481 nds32_warn_func_return (tree decl)
1483 /* Naked functions are implemented entirely in assembly, including the
1484 return sequence, so suppress warnings about this. */
1485 return !nds32_naked_function_p (decl);
1489 /* Implementing the Varargs Macros. */
1491 static bool
1492 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1494 /* Return true so that all the named arguments for FUNCTION_ARG have named=1.
1495 If return false, for the variadic function, all named arguments EXCEPT
1496 the last are treated as named. */
1497 return true;
1501 /* Trampolines for Nested Functions. */
1503 static void
1504 nds32_asm_trampoline_template (FILE *f)
1506 if (TARGET_REDUCED_REGS)
1508 /* Trampoline is not supported on reduced-set registers yet. */
1509 sorry ("a nested function is not supported for reduced registers");
1511 else
1513 asm_fprintf (f, "\t! Trampoline code template\n");
1514 asm_fprintf (f, "\t! This code fragment will be copied "
1515 "into stack on demand\n");
1517 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1518 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1519 "! load nested function address\n");
1520 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1521 "! load chain_value\n");
1522 asm_fprintf (f, "\tjr\t$r15\n");
1525 /* Preserve space ($pc + 16) for saving chain_value,
1526 nds32_trampoline_init will fill the value in this slot. */
1527 asm_fprintf (f, "\t! space for saving chain_value\n");
1528 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1530 /* Preserve space ($pc + 20) for saving nested function address,
1531 nds32_trampoline_init will fill the value in this slot. */
1532 asm_fprintf (f, "\t! space for saving nested function address\n");
1533 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1536 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1537 static void
1538 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1540 int i;
1542 /* Nested function address. */
1543 rtx fnaddr;
1544 /* The memory rtx that is going to
1545 be filled with chain_value. */
1546 rtx chain_value_mem;
1547 /* The memory rtx that is going to
1548 be filled with nested function address. */
1549 rtx nested_func_mem;
1551 /* Start address of trampoline code in stack, for doing cache sync. */
1552 rtx sync_cache_addr;
1553 /* Temporary register for sync instruction. */
1554 rtx tmp_reg;
1555 /* Instruction-cache sync instruction,
1556 requesting an argument as starting address. */
1557 rtx isync_insn;
1558 /* For convenience reason of doing comparison. */
1559 int tramp_align_in_bytes;
1561 /* Trampoline is not supported on reduced-set registers yet. */
1562 if (TARGET_REDUCED_REGS)
1563 sorry ("a nested function is not supported for reduced registers");
1565 /* STEP 1: Copy trampoline code template into stack,
1566 fill up essential data into stack. */
1568 /* Extract nested function address rtx. */
1569 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1571 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1572 We have nds32_asm_trampoline_template() to emit template pattern. */
1573 emit_block_move (m_tramp, assemble_trampoline_template (),
1574 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1576 /* After copying trampoline code into stack,
1577 fill chain_value into stack. */
1578 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1579 emit_move_insn (chain_value_mem, chain_value);
1580 /* After copying trampoline code int stack,
1581 fill nested function address into stack. */
1582 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1583 emit_move_insn (nested_func_mem, fnaddr);
1585 /* STEP 2: Sync instruction-cache. */
1587 /* We have successfully filled trampoline code into stack.
1588 However, in order to execute code in stack correctly,
1589 we must sync instruction cache. */
1590 sync_cache_addr = XEXP (m_tramp, 0);
1591 tmp_reg = gen_reg_rtx (SImode);
1592 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1594 /* Because nds32_cache_block_size is in bytes,
1595 we get trampoline alignment in bytes for convenient comparison. */
1596 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1598 if (tramp_align_in_bytes >= nds32_cache_block_size
1599 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1601 /* Under this condition, the starting address of trampoline
1602 must be aligned to the starting address of each cache block
1603 and we do not have to worry about cross-boundary issue. */
1604 for (i = 0;
1605 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1606 / nds32_cache_block_size;
1607 i++)
1609 emit_move_insn (tmp_reg,
1610 plus_constant (Pmode, sync_cache_addr,
1611 nds32_cache_block_size * i));
1612 emit_insn (isync_insn);
1615 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1617 /* The starting address of trampoline code
1618 may not be aligned to the cache block,
1619 so the trampoline code may be across two cache block.
1620 We need to sync the last element, which is 4-byte size,
1621 of trampoline template. */
1622 for (i = 0;
1623 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1624 / nds32_cache_block_size;
1625 i++)
1627 emit_move_insn (tmp_reg,
1628 plus_constant (Pmode, sync_cache_addr,
1629 nds32_cache_block_size * i));
1630 emit_insn (isync_insn);
1633 /* The last element of trampoline template is 4-byte size. */
1634 emit_move_insn (tmp_reg,
1635 plus_constant (Pmode, sync_cache_addr,
1636 TRAMPOLINE_SIZE - 4));
1637 emit_insn (isync_insn);
1639 else
1641 /* This is the simplest case.
1642 Because TRAMPOLINE_SIZE is less than or
1643 equal to nds32_cache_block_size,
1644 we can just sync start address and
1645 the last element of trampoline code. */
1647 /* Sync starting address of tampoline code. */
1648 emit_move_insn (tmp_reg, sync_cache_addr);
1649 emit_insn (isync_insn);
1650 /* Sync the last element, which is 4-byte size,
1651 of trampoline template. */
1652 emit_move_insn (tmp_reg,
1653 plus_constant (Pmode, sync_cache_addr,
1654 TRAMPOLINE_SIZE - 4));
1655 emit_insn (isync_insn);
1658 /* Set instruction serialization barrier
1659 to guarantee the correct operations. */
1660 emit_insn (gen_unspec_volatile_isb ());
1664 /* Addressing Modes. */
1666 static bool
1667 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1669 /* For (mem:DI addr) or (mem:DF addr) case,
1670 we only allow 'addr' to be [reg], [symbol_ref],
1671 [const], or [reg + const_int] pattern. */
1672 if (mode == DImode || mode == DFmode)
1674 /* Allow [Reg + const_int] addressing mode. */
1675 if (GET_CODE (x) == PLUS)
1677 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1678 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1679 && CONST_INT_P (XEXP (x, 1)))
1680 return true;
1682 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1683 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1684 && CONST_INT_P (XEXP (x, 0)))
1685 return true;
1688 /* Now check [reg], [symbol_ref], and [const]. */
1689 if (GET_CODE (x) != REG
1690 && GET_CODE (x) != SYMBOL_REF
1691 && GET_CODE (x) != CONST)
1692 return false;
1695 /* Check if 'x' is a valid address. */
1696 switch (GET_CODE (x))
1698 case REG:
1699 /* (mem (reg A)) => [Ra] */
1700 return nds32_address_register_rtx_p (x, strict);
1702 case SYMBOL_REF:
1704 if (!TARGET_GP_DIRECT
1705 && (reload_completed
1706 || reload_in_progress
1707 || lra_in_progress))
1708 return false;
1710 /* (mem (symbol_ref A)) => [symbol_ref] */
1711 return !currently_expanding_to_rtl;
1713 case CONST:
1715 if (!TARGET_GP_DIRECT
1716 && (reload_completed
1717 || reload_in_progress
1718 || lra_in_progress))
1719 return false;
1721 /* (mem (const (...)))
1722 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1723 if (GET_CODE (XEXP (x, 0)) == PLUS)
1725 rtx plus_op = XEXP (x, 0);
1727 rtx op0 = XEXP (plus_op, 0);
1728 rtx op1 = XEXP (plus_op, 1);
1730 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1731 return true;
1732 else
1733 return false;
1736 return false;
1738 case POST_MODIFY:
1739 /* (mem (post_modify (reg) (plus (reg) (reg))))
1740 => [Ra], Rb */
1741 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1742 => [Ra], const_int */
1743 if (GET_CODE (XEXP (x, 0)) == REG
1744 && GET_CODE (XEXP (x, 1)) == PLUS)
1746 rtx plus_op = XEXP (x, 1);
1748 rtx op0 = XEXP (plus_op, 0);
1749 rtx op1 = XEXP (plus_op, 1);
1751 if (nds32_address_register_rtx_p (op0, strict)
1752 && nds32_legitimate_index_p (mode, op1, strict))
1753 return true;
1754 else
1755 return false;
1758 return false;
1760 case POST_INC:
1761 case POST_DEC:
1762 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
1763 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
1764 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
1765 We only need to deal with register Ra. */
1766 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
1767 return true;
1768 else
1769 return false;
1771 case PLUS:
1772 /* (mem (plus reg const_int))
1773 => [Ra + imm] */
1774 /* (mem (plus reg reg))
1775 => [Ra + Rb] */
1776 /* (mem (plus (mult reg const_int) reg))
1777 => [Ra + Rb << sv] */
1778 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1779 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
1780 return true;
1781 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1782 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
1783 return true;
1784 else
1785 return false;
1787 case LO_SUM:
1788 if (!TARGET_GP_DIRECT)
1789 return true;
1791 default:
1792 return false;
1797 /* Describing Relative Costs of Operations. */
1799 static int
1800 nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1801 reg_class_t from,
1802 reg_class_t to)
1804 if (from == HIGH_REGS || to == HIGH_REGS)
1805 return 6;
1807 return 2;
1810 static int
1811 nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1812 reg_class_t rclass ATTRIBUTE_UNUSED,
1813 bool in ATTRIBUTE_UNUSED)
1815 return 8;
1818 /* This target hook describes the relative costs of RTL expressions.
1819 Return 'true' when all subexpressions of x have been processed.
1820 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
1821 Refer to gcc/rtlanal.c for more information. */
1822 static bool
1823 nds32_rtx_costs (rtx x,
1824 int code,
1825 int outer_code,
1826 int opno,
1827 int *total,
1828 bool speed)
1830 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
1833 static int
1834 nds32_address_cost (rtx address,
1835 enum machine_mode mode,
1836 addr_space_t as,
1837 bool speed)
1839 return nds32_address_cost_impl (address, mode, as, speed);
1843 /* Defining the Output Assembler Language. */
1845 /* -- The Overall Framework of an Assembler File. */
1847 static void
1848 nds32_asm_file_start (void)
1850 default_file_start ();
1852 /* Tell assembler which ABI we are using. */
1853 fprintf (asm_out_file, "\t! ABI version\n");
1854 fprintf (asm_out_file, "\t.abi_2\n");
1856 /* Tell assembler that this asm code is generated by compiler. */
1857 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
1858 fprintf (asm_out_file, "\t.flag\tverbatim\n");
1859 /* Give assembler the size of each vector for interrupt handler. */
1860 fprintf (asm_out_file, "\t! This vector size directive is required "
1861 "for checking inconsistency on interrupt handler\n");
1862 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
1864 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
1865 the compiler may produce 'la $fp,_FP_BASE_' instruction
1866 at prologue for fp-as-gp optimization.
1867 We should emit weak reference of _FP_BASE_ to avoid undefined reference
1868 in case user does not pass '--relax' option to linker. */
1869 if (TARGET_FORCE_FP_AS_GP || optimize_size)
1871 fprintf (asm_out_file, "\t! This weak reference is required to do "
1872 "fp-as-gp link time optimization\n");
1873 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
1875 /* If user enables '-mex9', we should emit relaxation directive
1876 to tell linker that this file is allowed to do ex9 optimization. */
1877 if (TARGET_EX9)
1879 fprintf (asm_out_file, "\t! This relaxation directive is required "
1880 "to do ex9 link time optimization\n");
1881 fprintf (asm_out_file, "\t.relax\tex9\n");
1884 fprintf (asm_out_file, "\t! ------------------------------------\n");
1886 if (TARGET_ISA_V2)
1887 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
1888 if (TARGET_ISA_V3)
1889 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
1890 if (TARGET_ISA_V3M)
1891 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
1893 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
1894 ((TARGET_BIG_ENDIAN) ? "big-endian"
1895 : "little-endian"));
1897 fprintf (asm_out_file, "\t! ------------------------------------\n");
1899 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
1900 ((TARGET_CMOV) ? "Yes"
1901 : "No"));
1902 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
1903 ((TARGET_PERF_EXT) ? "Yes"
1904 : "No"));
1906 fprintf (asm_out_file, "\t! ------------------------------------\n");
1908 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
1909 ((TARGET_V3PUSH) ? "Yes"
1910 : "No"));
1911 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
1912 ((TARGET_16_BIT) ? "Yes"
1913 : "No"));
1914 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
1915 ((TARGET_GP_DIRECT) ? "Yes"
1916 : "No"));
1917 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
1918 ((TARGET_REDUCED_REGS) ? "Yes"
1919 : "No"));
1921 fprintf (asm_out_file, "\t! ------------------------------------\n");
1923 if (optimize_size)
1924 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
1925 else
1926 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
1928 fprintf (asm_out_file, "\t! ------------------------------------\n");
1930 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
1931 nds32_cache_block_size);
1933 fprintf (asm_out_file, "\t! ------------------------------------\n");
1935 nds32_asm_file_start_for_isr ();
1938 static void
1939 nds32_asm_file_end (void)
1941 nds32_asm_file_end_for_isr ();
1943 fprintf (asm_out_file, "\t! ------------------------------------\n");
1946 /* -- Output and Generation of Labels. */
1948 static void
1949 nds32_asm_globalize_label (FILE *stream, const char *name)
1951 fputs ("\t.global\t", stream);
1952 assemble_name (stream, name);
1953 fputs ("\n", stream);
1956 /* -- Output of Assembler Instructions. */
1958 static void
1959 nds32_print_operand (FILE *stream, rtx x, int code)
1961 int op_value;
1963 switch (code)
1965 case 0 :
1966 /* Do nothing special. */
1967 break;
1969 case 'V':
1970 /* 'x' is supposed to be CONST_INT, get the value. */
1971 gcc_assert (CONST_INT_P (x));
1972 op_value = INTVAL (x);
1974 /* According to the Andes architecture,
1975 the system/user register index range is 0 ~ 1023.
1976 In order to avoid conflict between user-specified-integer value
1977 and enum-specified-register value,
1978 the 'enum nds32_intrinsic_registers' value
1979 in nds32_intrinsic.h starts from 1024. */
1980 if (op_value < 1024 && op_value >= 0)
1982 /* If user gives integer value directly (0~1023),
1983 we just print out the value. */
1984 fprintf (stream, "%d", op_value);
1986 else if (op_value < 0
1987 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
1988 + 1024))
1990 /* The enum index value for array size is out of range. */
1991 error ("intrinsic register index is out of range");
1993 else
1995 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
1996 we can print out register name. Remember to substract 1024. */
1997 fprintf (stream, "%s",
1998 nds32_intrinsic_register_names[op_value - 1024]);
2001 /* No need to handle following process, so return immediately. */
2002 return;
2004 default :
2005 /* Unknown flag. */
2006 output_operand_lossage ("invalid operand output code");
2007 break;
2010 switch (GET_CODE (x))
2012 case LABEL_REF:
2013 case SYMBOL_REF:
2014 output_addr_const (stream, x);
2015 break;
2017 case REG:
2018 /* Forbid using static chain register ($r16)
2019 on reduced-set registers configuration. */
2020 if (TARGET_REDUCED_REGS
2021 && REGNO (x) == STATIC_CHAIN_REGNUM)
2022 sorry ("a nested function is not supported for reduced registers");
2024 /* Normal cases, print out register name. */
2025 fputs (reg_names[REGNO (x)], stream);
2026 break;
2028 case MEM:
2029 output_address (XEXP (x, 0));
2030 break;
2032 case CODE_LABEL:
2033 case CONST_INT:
2034 case CONST:
2035 output_addr_const (stream, x);
2036 break;
2038 default:
2039 /* Generally, output_addr_const () is able to handle most cases.
2040 We want to see what CODE could appear,
2041 so we use gcc_unreachable() to stop it. */
2042 debug_rtx (x);
2043 gcc_unreachable ();
2044 break;
2048 static void
2049 nds32_print_operand_address (FILE *stream, rtx x)
2051 rtx op0, op1;
2053 switch (GET_CODE (x))
2055 case SYMBOL_REF:
2056 case CONST:
2057 /* [ + symbol_ref] */
2058 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2059 fputs ("[ + ", stream);
2060 output_addr_const (stream, x);
2061 fputs ("]", stream);
2062 break;
2064 case REG:
2065 /* Forbid using static chain register ($r16)
2066 on reduced-set registers configuration. */
2067 if (TARGET_REDUCED_REGS
2068 && REGNO (x) == STATIC_CHAIN_REGNUM)
2069 sorry ("a nested function is not supported for reduced registers");
2071 /* [Ra] */
2072 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2073 break;
2075 case PLUS:
2076 op0 = XEXP (x, 0);
2077 op1 = XEXP (x, 1);
2079 /* Checking op0, forbid using static chain register ($r16)
2080 on reduced-set registers configuration. */
2081 if (TARGET_REDUCED_REGS
2082 && REG_P (op0)
2083 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2084 sorry ("a nested function is not supported for reduced registers");
2085 /* Checking op1, forbid using static chain register ($r16)
2086 on reduced-set registers configuration. */
2087 if (TARGET_REDUCED_REGS
2088 && REG_P (op1)
2089 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2090 sorry ("a nested function is not supported for reduced registers");
2092 if (REG_P (op0) && CONST_INT_P (op1))
2094 /* [Ra + imm] */
2095 fprintf (stream, "[%s + (%d)]",
2096 reg_names[REGNO (op0)], (int)INTVAL (op1));
2098 else if (REG_P (op0) && REG_P (op1))
2100 /* [Ra + Rb] */
2101 fprintf (stream, "[%s + %s]",
2102 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2104 else if (GET_CODE (op0) == MULT && REG_P (op1))
2106 /* [Ra + Rb << sv]
2107 From observation, the pattern looks like:
2108 (plus:SI (mult:SI (reg:SI 58)
2109 (const_int 4 [0x4]))
2110 (reg/f:SI 57)) */
2111 int sv;
2113 /* We need to set sv to output shift value. */
2114 if (INTVAL (XEXP (op0, 1)) == 1)
2115 sv = 0;
2116 else if (INTVAL (XEXP (op0, 1)) == 2)
2117 sv = 1;
2118 else if (INTVAL (XEXP (op0, 1)) == 4)
2119 sv = 2;
2120 else
2121 gcc_unreachable ();
2123 fprintf (stream, "[%s + %s << %d]",
2124 reg_names[REGNO (op1)],
2125 reg_names[REGNO (XEXP (op0, 0))],
2126 sv);
2128 else
2130 /* The control flow is not supposed to be here. */
2131 debug_rtx (x);
2132 gcc_unreachable ();
2135 break;
2137 case POST_MODIFY:
2138 /* (post_modify (regA) (plus (regA) (regB)))
2139 (post_modify (regA) (plus (regA) (const_int)))
2140 We would like to extract
2141 regA and regB (or const_int) from plus rtx. */
2142 op0 = XEXP (XEXP (x, 1), 0);
2143 op1 = XEXP (XEXP (x, 1), 1);
2145 /* Checking op0, forbid using static chain register ($r16)
2146 on reduced-set registers configuration. */
2147 if (TARGET_REDUCED_REGS
2148 && REG_P (op0)
2149 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2150 sorry ("a nested function is not supported for reduced registers");
2151 /* Checking op1, forbid using static chain register ($r16)
2152 on reduced-set registers configuration. */
2153 if (TARGET_REDUCED_REGS
2154 && REG_P (op1)
2155 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2156 sorry ("a nested function is not supported for reduced registers");
2158 if (REG_P (op0) && REG_P (op1))
2160 /* [Ra], Rb */
2161 fprintf (stream, "[%s], %s",
2162 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2164 else if (REG_P (op0) && CONST_INT_P (op1))
2166 /* [Ra], imm */
2167 fprintf (stream, "[%s], %d",
2168 reg_names[REGNO (op0)], (int)INTVAL (op1));
2170 else
2172 /* The control flow is not supposed to be here. */
2173 debug_rtx (x);
2174 gcc_unreachable ();
2177 break;
2179 case POST_INC:
2180 case POST_DEC:
2181 op0 = XEXP (x, 0);
2183 /* Checking op0, forbid using static chain register ($r16)
2184 on reduced-set registers configuration. */
2185 if (TARGET_REDUCED_REGS
2186 && REG_P (op0)
2187 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2188 sorry ("a nested function is not supported for reduced registers");
2190 if (REG_P (op0))
2192 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2193 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2194 We only need to deal with register Ra. */
2195 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2197 else
2199 /* The control flow is not supposed to be here. */
2200 debug_rtx (x);
2201 gcc_unreachable ();
2204 break;
2206 default :
2207 /* Generally, output_addr_const () is able to handle most cases.
2208 We want to see what CODE could appear,
2209 so we use gcc_unreachable() to stop it. */
2210 debug_rtx (x);
2211 gcc_unreachable ();
2212 break;
2217 /* Defining target-specific uses of __attribute__. */
2219 /* Add some checking after merging attributes. */
2220 static tree
2221 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2223 tree combined_attrs;
2225 /* Create combined attributes. */
2226 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2227 DECL_ATTRIBUTES (newdecl));
2229 /* Since newdecl is acutally a duplicate of olddecl,
2230 we can take olddecl for some operations. */
2231 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2233 /* Check isr-specific attributes conflict. */
2234 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2237 return combined_attrs;
2240 /* Add some checking when inserting attributes. */
2241 static void
2242 nds32_insert_attributes (tree decl, tree *attributes)
2244 /* For function declaration, we need to check isr-specific attributes:
2245 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2246 2. Check valid integer value for interrupt/exception.
2247 3. Check valid integer value for reset.
2248 4. Check valid function for nmi/warm. */
2249 if (TREE_CODE (decl) == FUNCTION_DECL)
2251 tree func_attrs;
2252 tree intr, excp, reset;
2254 /* Pick up function attributes. */
2255 func_attrs = *attributes;
2257 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2258 nds32_check_isr_attrs_conflict (decl, func_attrs);
2260 /* Now we are starting to check valid id value
2261 for interrupt/exception/reset.
2262 Note that we ONLY check its validity here.
2263 To construct isr vector information, it is still performed
2264 by nds32_construct_isr_vectors_information(). */
2265 intr = lookup_attribute ("interrupt", func_attrs);
2266 excp = lookup_attribute ("exception", func_attrs);
2267 reset = lookup_attribute ("reset", func_attrs);
2269 if (intr || excp)
2271 /* Deal with interrupt/exception. */
2272 tree id_list;
2273 unsigned int lower_bound, upper_bound;
2275 /* The way to handle interrupt or exception is the same,
2276 we just need to take care of actual vector number.
2277 For interrupt(0..63), the actual vector number is (9..72).
2278 For exception(1..8), the actual vector number is (1..8). */
2279 lower_bound = (intr) ? (0) : (1);
2280 upper_bound = (intr) ? (63) : (8);
2282 /* Prepare id list so that we can traverse id value. */
2283 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2285 /* 2. Check valid integer value for interrupt/exception. */
2286 while (id_list)
2288 tree id;
2290 /* Pick up each vector id value. */
2291 id = TREE_VALUE (id_list);
2292 /* Issue error if it is not a valid integer value. */
2293 if (TREE_CODE (id) != INTEGER_CST
2294 || wi::ltu_p (id, lower_bound)
2295 || wi::gtu_p (id, upper_bound))
2296 error ("invalid id value for interrupt/exception attribute");
2298 /* Advance to next id. */
2299 id_list = TREE_CHAIN (id_list);
2302 else if (reset)
2304 /* Deal with reset. */
2305 tree id_list;
2306 tree id;
2307 tree nmi, warm;
2308 unsigned int lower_bound;
2309 unsigned int upper_bound;
2311 /* Prepare id_list and identify id value so that
2312 we can check if total number of vectors is valid. */
2313 id_list = TREE_VALUE (reset);
2314 id = TREE_VALUE (id_list);
2316 /* The maximum numbers for user's interrupt is 64. */
2317 lower_bound = 0;
2318 upper_bound = 64;
2320 /* 3. Check valid integer value for reset. */
2321 if (TREE_CODE (id) != INTEGER_CST
2322 || wi::ltu_p (id, lower_bound)
2323 || wi::gtu_p (id, upper_bound))
2324 error ("invalid id value for reset attribute");
2326 /* 4. Check valid function for nmi/warm. */
2327 nmi = lookup_attribute ("nmi", func_attrs);
2328 warm = lookup_attribute ("warm", func_attrs);
2330 if (nmi != NULL_TREE)
2332 tree nmi_func_list;
2333 tree nmi_func;
2335 nmi_func_list = TREE_VALUE (nmi);
2336 nmi_func = TREE_VALUE (nmi_func_list);
2338 /* Issue error if it is not a valid nmi function. */
2339 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2340 error ("invalid nmi function for reset attribute");
2343 if (warm != NULL_TREE)
2345 tree warm_func_list;
2346 tree warm_func;
2348 warm_func_list = TREE_VALUE (warm);
2349 warm_func = TREE_VALUE (warm_func_list);
2351 /* Issue error if it is not a valid warm function. */
2352 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2353 error ("invalid warm function for reset attribute");
2356 else
2358 /* No interrupt, exception, or reset attribute is set. */
2359 return;
2364 static bool
2365 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2366 tree pop_target ATTRIBUTE_UNUSED)
2368 /* Currently, we do not parse any pragma target by ourself,
2369 so just simply return false. */
2370 return false;
2373 static void
2374 nds32_option_override (void)
2376 /* After all the command options have been parsed,
2377 we shall deal with some flags for changing compiler settings. */
2379 /* At first, we check if we have to strictly
2380 set some flags based on ISA family. */
2381 if (TARGET_ISA_V2)
2383 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2384 target_flags &= ~MASK_V3PUSH;
2386 if (TARGET_ISA_V3)
2388 /* Under V3 ISA, currently nothing should be strictly set. */
2390 if (TARGET_ISA_V3M)
2392 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2393 target_flags |= MASK_REDUCED_REGS;
2394 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2395 target_flags &= ~MASK_PERF_EXT;
2398 /* See if we are using reduced-set registers:
2399 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2400 If so, we must forbid using $r11~$r14, $r16~$r27. */
2401 if (TARGET_REDUCED_REGS)
2403 int r;
2405 /* Prevent register allocator from
2406 choosing it as doing register allocation. */
2407 for (r = 11; r <= 14; r++)
2408 fixed_regs[r] = call_used_regs[r] = 1;
2409 for (r = 16; r <= 27; r++)
2410 fixed_regs[r] = call_used_regs[r] = 1;
2413 /* See if user explicitly would like to use fp-as-gp optimization.
2414 If so, we must prevent $fp from being allocated
2415 during register allocation. */
2416 if (TARGET_FORCE_FP_AS_GP)
2417 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2419 if (!TARGET_16_BIT)
2421 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2422 target_flags &= ~MASK_V3PUSH;
2425 /* Currently, we don't support PIC code generation yet. */
2426 if (flag_pic)
2427 sorry ("not support -fpic");
2431 /* Miscellaneous Parameters. */
2433 static void
2434 nds32_init_builtins (void)
2436 nds32_init_builtins_impl ();
2439 static rtx
2440 nds32_expand_builtin (tree exp,
2441 rtx target,
2442 rtx subtarget,
2443 enum machine_mode mode,
2444 int ignore)
2446 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2450 /* ------------------------------------------------------------------------ */
2452 /* PART 4: Implemet extern function definitions,
2453 the prototype is in nds32-protos.h. */
2455 /* Defining Data Structures for Per-function Information. */
2457 void
2458 nds32_init_expanders (void)
2460 /* Arrange to initialize and mark the machine per-function status. */
2461 init_machine_status = nds32_init_machine_status;
2465 /* Register Usage. */
2467 /* -- How Values Fit in Registers. */
2470 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2471 enum machine_mode mode)
2473 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2477 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
2479 /* Restrict double-word quantities to even register pairs. */
2480 if (HARD_REGNO_NREGS (regno, mode) == 1
2481 || !((regno) & 1))
2482 return 1;
2484 return 0;
2488 /* Register Classes. */
2490 enum reg_class
2491 nds32_regno_reg_class (int regno)
2493 /* Refer to nds32.h for more register class details. */
2495 if (regno >= 0 && regno <= 7)
2496 return LOW_REGS;
2497 else if (regno >= 8 && regno <= 11)
2498 return MIDDLE_REGS;
2499 else if (regno >= 12 && regno <= 14)
2500 return HIGH_REGS;
2501 else if (regno == 15)
2502 return R15_TA_REG;
2503 else if (regno >= 16 && regno <= 19)
2504 return MIDDLE_REGS;
2505 else if (regno >= 20 && regno <= 31)
2506 return HIGH_REGS;
2507 else if (regno == 32 || regno == 33)
2508 return FRAME_REGS;
2509 else
2510 return NO_REGS;
2514 /* Stack Layout and Calling Conventions. */
2516 /* -- Basic Stack Layout. */
2519 nds32_return_addr_rtx (int count,
2520 rtx frameaddr ATTRIBUTE_UNUSED)
2522 /* There is no way to determine the return address
2523 if frameaddr is the frame that has 'count' steps
2524 up from current frame. */
2525 if (count != 0)
2526 return NULL_RTX;
2528 /* If count == 0, it means we are at current frame,
2529 the return address is $r30 ($lp). */
2530 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2533 /* -- Eliminating Frame Pointer and Arg Pointer. */
2535 HOST_WIDE_INT
2536 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2538 HOST_WIDE_INT offset;
2540 /* Compute and setup stack frame size.
2541 The result will be in cfun->machine. */
2542 nds32_compute_stack_frame ();
2544 /* Remember to consider
2545 cfun->machine->callee_saved_area_padding_bytes
2546 when calculating offset. */
2547 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2549 offset = (cfun->machine->fp_size
2550 + cfun->machine->gp_size
2551 + cfun->machine->lp_size
2552 + cfun->machine->callee_saved_regs_size
2553 + cfun->machine->callee_saved_area_padding_bytes
2554 + cfun->machine->local_size
2555 + cfun->machine->out_args_size);
2557 else if (from_reg == ARG_POINTER_REGNUM
2558 && to_reg == HARD_FRAME_POINTER_REGNUM)
2560 offset = 0;
2562 else if (from_reg == FRAME_POINTER_REGNUM
2563 && to_reg == STACK_POINTER_REGNUM)
2565 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2567 else if (from_reg == FRAME_POINTER_REGNUM
2568 && to_reg == HARD_FRAME_POINTER_REGNUM)
2570 offset = (-1) * (cfun->machine->fp_size
2571 + cfun->machine->gp_size
2572 + cfun->machine->lp_size
2573 + cfun->machine->callee_saved_regs_size
2574 + cfun->machine->callee_saved_area_padding_bytes);
2576 else
2578 gcc_unreachable ();
2581 return offset;
2584 /* -- Passing Arguments in Registers. */
2586 void
2587 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2588 tree fntype ATTRIBUTE_UNUSED,
2589 rtx libname ATTRIBUTE_UNUSED,
2590 tree fndecl ATTRIBUTE_UNUSED,
2591 int n_named_args ATTRIBUTE_UNUSED)
2593 /* Initial available registers
2594 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2595 for passing arguments. */
2596 cum->reg_offset = 0;
2599 /* -- Function Entry and Exit. */
2601 /* Function for normal multiple push prologue. */
2602 void
2603 nds32_expand_prologue (void)
2605 int fp_adjust;
2606 int sp_adjust;
2607 int en4_const;
2609 rtx Rb, Re;
2610 rtx push_insn;
2611 rtx fp_adjust_insn, sp_adjust_insn;
2613 /* Before computing everything for stack frame size,
2614 we check if it is still worth to use fp_as_gp optimization.
2615 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2616 so that $fp will be saved on stack. */
2617 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
2619 /* Compute and setup stack frame size.
2620 The result will be in cfun->machine. */
2621 nds32_compute_stack_frame ();
2623 /* If the function is 'naked',
2624 we do not have to generate prologue code fragment. */
2625 if (cfun->machine->naked_p)
2626 return;
2628 /* Get callee_first_regno and callee_last_regno. */
2629 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2630 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2632 /* push_insn = gen_stack_push_multiple(first_regno, last_regno),
2633 the pattern 'stack_push_multiple' is implemented in nds32.md.
2634 For En4 field, we have to calculate its constant value.
2635 Refer to Andes ISA for more information. */
2636 en4_const = 0;
2637 if (cfun->machine->fp_size)
2638 en4_const += 8;
2639 if (cfun->machine->gp_size)
2640 en4_const += 4;
2641 if (cfun->machine->lp_size)
2642 en4_const += 2;
2644 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2645 to be saved, we don't have to create multiple push instruction.
2646 Otherwise, a multiple push instruction is needed. */
2647 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2649 /* Create multiple push instruction rtx. */
2650 push_insn = nds32_gen_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
2651 /* Emit rtx into instructions list and receive INSN rtx form. */
2652 push_insn = emit_insn (push_insn);
2654 /* The insn rtx 'push_insn' will change frame layout.
2655 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2656 generate CFI (Call Frame Information) stuff. */
2657 RTX_FRAME_RELATED_P (push_insn) = 1;
2660 /* Check frame_pointer_needed to see
2661 if we shall emit fp adjustment instruction. */
2662 if (frame_pointer_needed)
2664 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2665 + (4 * callee-saved-registers)
2666 Note: No need to adjust
2667 cfun->machine->callee_saved_area_padding_bytes,
2668 because, at this point, stack pointer is just
2669 at the position after push instruction. */
2670 fp_adjust = cfun->machine->fp_size
2671 + cfun->machine->gp_size
2672 + cfun->machine->lp_size
2673 + cfun->machine->callee_saved_regs_size;
2674 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2675 stack_pointer_rtx,
2676 GEN_INT (fp_adjust));
2677 /* Emit rtx into instructions list and receive INSN rtx form. */
2678 fp_adjust_insn = emit_insn (fp_adjust_insn);
2681 /* Adjust $sp = $sp - local_size - out_args_size
2682 - callee_saved_area_padding_bytes. */
2683 sp_adjust = cfun->machine->local_size
2684 + cfun->machine->out_args_size
2685 + cfun->machine->callee_saved_area_padding_bytes;
2686 /* sp_adjust value may be out of range of the addi instruction,
2687 create alternative add behavior with TA_REGNUM if necessary,
2688 using NEGATIVE value to tell that we are decreasing address. */
2689 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2690 if (sp_adjust)
2692 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2693 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2694 stack_pointer_rtx,
2695 GEN_INT (-1 * sp_adjust));
2696 /* Emit rtx into instructions list and receive INSN rtx form. */
2697 sp_adjust_insn = emit_insn (sp_adjust_insn);
2699 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2700 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2701 generate CFI (Call Frame Information) stuff. */
2702 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2705 /* Prevent the instruction scheduler from
2706 moving instructions across the boundary. */
2707 emit_insn (gen_blockage ());
2710 /* Function for normal multiple pop epilogue. */
2711 void
2712 nds32_expand_epilogue (void)
2714 int sp_adjust;
2715 int en4_const;
2717 rtx Rb, Re;
2718 rtx pop_insn;
2719 rtx sp_adjust_insn;
2721 /* Compute and setup stack frame size.
2722 The result will be in cfun->machine. */
2723 nds32_compute_stack_frame ();
2725 /* Prevent the instruction scheduler from
2726 moving instructions across the boundary. */
2727 emit_insn (gen_blockage ());
2729 /* If the function is 'naked', we do not have to generate
2730 epilogue code fragment BUT 'ret' instruction. */
2731 if (cfun->machine->naked_p)
2733 /* Generate return instruction by using
2734 unspec_volatile_func_return pattern.
2735 Make sure this instruction is after gen_blockage().
2736 NOTE that $lp will become 'live'
2737 after this instruction has been emitted. */
2738 emit_insn (gen_unspec_volatile_func_return ());
2739 return;
2742 if (frame_pointer_needed)
2744 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
2745 - (4 * callee-saved-registers)
2746 Note: No need to adjust
2747 cfun->machine->callee_saved_area_padding_bytes,
2748 because we want to adjust stack pointer
2749 to the position for pop instruction. */
2750 sp_adjust = cfun->machine->fp_size
2751 + cfun->machine->gp_size
2752 + cfun->machine->lp_size
2753 + cfun->machine->callee_saved_regs_size;
2754 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2755 hard_frame_pointer_rtx,
2756 GEN_INT (-1 * sp_adjust));
2757 /* Emit rtx into instructions list and receive INSN rtx form. */
2758 sp_adjust_insn = emit_insn (sp_adjust_insn);
2760 else
2762 /* If frame pointer is NOT needed,
2763 we cannot calculate the sp adjustment from frame pointer.
2764 Instead, we calculate the adjustment by local_size,
2765 out_args_size, and callee_saved_area_padding_bytes.
2766 Notice that such sp adjustment value may be out of range,
2767 so we have to deal with it as well. */
2769 /* Adjust $sp = $sp + local_size + out_args_size
2770 + callee_saved_area_padding_bytes. */
2771 sp_adjust = cfun->machine->local_size
2772 + cfun->machine->out_args_size
2773 + cfun->machine->callee_saved_area_padding_bytes;
2774 /* sp_adjust value may be out of range of the addi instruction,
2775 create alternative add behavior with TA_REGNUM if necessary,
2776 using POSITIVE value to tell that we are increasing address. */
2777 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
2778 if (sp_adjust)
2780 /* Generate sp adjustment instruction
2781 if and only if sp_adjust != 0. */
2782 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2783 stack_pointer_rtx,
2784 GEN_INT (sp_adjust));
2785 /* Emit rtx into instructions list and receive INSN rtx form. */
2786 sp_adjust_insn = emit_insn (sp_adjust_insn);
2790 /* Get callee_first_regno and callee_last_regno. */
2791 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2792 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2794 /* pop_insn = gen_stack_pop_multiple(first_regno, last_regno),
2795 the pattern 'stack_pop_multiple' is implementad in nds32.md.
2796 For En4 field, we have to calculate its constant value.
2797 Refer to Andes ISA for more information. */
2798 en4_const = 0;
2799 if (cfun->machine->fp_size)
2800 en4_const += 8;
2801 if (cfun->machine->gp_size)
2802 en4_const += 4;
2803 if (cfun->machine->lp_size)
2804 en4_const += 2;
2806 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2807 to be saved, we don't have to create multiple pop instruction.
2808 Otherwise, a multiple pop instruction is needed. */
2809 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2811 /* Create multiple pop instruction rtx. */
2812 pop_insn = nds32_gen_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
2813 /* Emit pop instruction. */
2814 emit_insn (pop_insn);
2817 /* Generate return instruction by using
2818 unspec_volatile_func_return pattern. */
2819 emit_insn (gen_unspec_volatile_func_return ());
2822 /* Function for v3push prologue. */
2823 void
2824 nds32_expand_prologue_v3push (void)
2826 int fp_adjust;
2827 int sp_adjust;
2829 rtx Rb, Re;
2830 rtx push_insn;
2831 rtx fp_adjust_insn, sp_adjust_insn;
2833 /* Before computing everything for stack frame size,
2834 we check if it is still worth to use fp_as_gp optimization.
2835 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2836 so that $fp will be saved on stack. */
2837 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
2839 /* Compute and setup stack frame size.
2840 The result will be in cfun->machine. */
2841 nds32_compute_stack_frame ();
2843 /* If the function is 'naked',
2844 we do not have to generate prologue code fragment. */
2845 if (cfun->machine->naked_p)
2846 return;
2848 /* Get callee_first_regno and callee_last_regno. */
2849 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2850 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2852 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
2853 where imm8u has to be 8-byte alignment. */
2854 sp_adjust = cfun->machine->local_size
2855 + cfun->machine->out_args_size
2856 + cfun->machine->callee_saved_area_padding_bytes;
2858 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
2859 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
2861 /* We can use 'push25 Re,imm8u'. */
2863 /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
2864 the pattern 'stack_v3push' is implemented in nds32.md.
2865 The (const_int 14) means v3push always push { $fp $gp $lp }. */
2866 push_insn = nds32_gen_stack_v3push (Rb, Re,
2867 GEN_INT (14), GEN_INT (sp_adjust));
2868 /* emit rtx into instructions list and receive INSN rtx form */
2869 push_insn = emit_insn (push_insn);
2871 /* The insn rtx 'push_insn' will change frame layout.
2872 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2873 generate CFI (Call Frame Information) stuff. */
2874 RTX_FRAME_RELATED_P (push_insn) = 1;
2876 /* Check frame_pointer_needed to see
2877 if we shall emit fp adjustment instruction. */
2878 if (frame_pointer_needed)
2880 /* adjust $fp = $sp + 4 ($fp size)
2881 + 4 ($gp size)
2882 + 4 ($lp size)
2883 + (4 * n) (callee-saved registers)
2884 + sp_adjust ('push25 Re,imm8u')
2885 Note: Since we use 'push25 Re,imm8u',
2886 the position of stack pointer is further
2887 changed after push instruction.
2888 Hence, we need to take sp_adjust value
2889 into consideration. */
2890 fp_adjust = cfun->machine->fp_size
2891 + cfun->machine->gp_size
2892 + cfun->machine->lp_size
2893 + cfun->machine->callee_saved_regs_size
2894 + sp_adjust;
2895 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2896 stack_pointer_rtx,
2897 GEN_INT (fp_adjust));
2898 /* Emit rtx into instructions list and receive INSN rtx form. */
2899 fp_adjust_insn = emit_insn (fp_adjust_insn);
2902 else
2904 /* We have to use 'push25 Re,0' and
2905 expand one more instruction to adjust $sp later. */
2907 /* push_insn = gen_stack_v3push(last_regno, sp_adjust),
2908 the pattern 'stack_v3push' is implemented in nds32.md.
2909 The (const_int 14) means v3push always push { $fp $gp $lp }. */
2910 push_insn = nds32_gen_stack_v3push (Rb, Re,
2911 GEN_INT (14), GEN_INT (0));
2912 /* Emit rtx into instructions list and receive INSN rtx form. */
2913 push_insn = emit_insn (push_insn);
2915 /* The insn rtx 'push_insn' will change frame layout.
2916 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2917 generate CFI (Call Frame Information) stuff. */
2918 RTX_FRAME_RELATED_P (push_insn) = 1;
2920 /* Check frame_pointer_needed to see
2921 if we shall emit fp adjustment instruction. */
2922 if (frame_pointer_needed)
2924 /* adjust $fp = $sp + 4 ($fp size)
2925 + 4 ($gp size)
2926 + 4 ($lp size)
2927 + (4 * n) (callee-saved registers)
2928 Note: Since we use 'push25 Re,0',
2929 the stack pointer is just at the position
2930 after push instruction.
2931 No need to take sp_adjust into consideration. */
2932 fp_adjust = cfun->machine->fp_size
2933 + cfun->machine->gp_size
2934 + cfun->machine->lp_size
2935 + cfun->machine->callee_saved_regs_size;
2936 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2937 stack_pointer_rtx,
2938 GEN_INT (fp_adjust));
2939 /* Emit rtx into instructions list and receive INSN rtx form. */
2940 fp_adjust_insn = emit_insn (fp_adjust_insn);
2943 /* Because we use 'push25 Re,0',
2944 we need to expand one more instruction to adjust $sp.
2945 However, sp_adjust value may be out of range of the addi instruction,
2946 create alternative add behavior with TA_REGNUM if necessary,
2947 using NEGATIVE value to tell that we are decreasing address. */
2948 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2949 if (sp_adjust)
2951 /* Generate sp adjustment instruction
2952 if and only if sp_adjust != 0. */
2953 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2954 stack_pointer_rtx,
2955 GEN_INT (-1 * sp_adjust));
2956 /* Emit rtx into instructions list and receive INSN rtx form. */
2957 sp_adjust_insn = emit_insn (sp_adjust_insn);
2959 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2960 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2961 generate CFI (Call Frame Information) stuff. */
2962 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2966 /* Prevent the instruction scheduler from
2967 moving instructions across the boundary. */
2968 emit_insn (gen_blockage ());
2971 /* Function for v3pop epilogue. */
2972 void
2973 nds32_expand_epilogue_v3pop (void)
2975 int sp_adjust;
2977 rtx Rb, Re;
2978 rtx pop_insn;
2979 rtx sp_adjust_insn;
2981 /* Compute and setup stack frame size.
2982 The result will be in cfun->machine. */
2983 nds32_compute_stack_frame ();
2985 /* Prevent the instruction scheduler from
2986 moving instructions across the boundary. */
2987 emit_insn (gen_blockage ());
2989 /* If the function is 'naked', we do not have to generate
2990 epilogue code fragment BUT 'ret' instruction. */
2991 if (cfun->machine->naked_p)
2993 /* Generate return instruction by using
2994 unspec_volatile_func_return pattern.
2995 Make sure this instruction is after gen_blockage().
2996 NOTE that $lp will become 'live'
2997 after this instruction has been emitted. */
2998 emit_insn (gen_unspec_volatile_func_return ());
2999 return;
3002 /* Get callee_first_regno and callee_last_regno. */
3003 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3004 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3006 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3007 where imm8u has to be 8-byte alignment. */
3008 sp_adjust = cfun->machine->local_size
3009 + cfun->machine->out_args_size
3010 + cfun->machine->callee_saved_area_padding_bytes;
3012 /* We have to consider alloca issue as well.
3013 If the function does call alloca(), the stack pointer is not fixed.
3014 In that case, we cannot use 'pop25 Re,imm8u' directly.
3015 We have to caculate stack pointer from frame pointer
3016 and then use 'pop25 Re,0'.
3017 Of course, the frame_pointer_needed should be nonzero
3018 if the function calls alloca(). */
3019 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3020 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3021 && !cfun->calls_alloca)
3023 /* We can use 'pop25 Re,imm8u'. */
3025 /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
3026 the pattern 'stack_v3pop' is implementad in nds32.md.
3027 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3028 pop_insn = nds32_gen_stack_v3pop (Rb, Re,
3029 GEN_INT (14), GEN_INT (sp_adjust));
3031 /* Emit pop instruction. */
3032 emit_insn (pop_insn);
3034 else
3036 /* We have to use 'pop25 Re,0', and prior to it,
3037 we must expand one more instruction to adjust $sp. */
3039 if (frame_pointer_needed)
3041 /* adjust $sp = $fp - 4 ($fp size)
3042 - 4 ($gp size)
3043 - 4 ($lp size)
3044 - (4 * n) (callee-saved registers)
3045 Note: No need to adjust
3046 cfun->machine->callee_saved_area_padding_bytes,
3047 because we want to adjust stack pointer
3048 to the position for pop instruction. */
3049 sp_adjust = cfun->machine->fp_size
3050 + cfun->machine->gp_size
3051 + cfun->machine->lp_size
3052 + cfun->machine->callee_saved_regs_size;
3053 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3054 hard_frame_pointer_rtx,
3055 GEN_INT (-1 * sp_adjust));
3056 /* Emit rtx into instructions list and receive INSN rtx form. */
3057 sp_adjust_insn = emit_insn (sp_adjust_insn);
3059 else
3061 /* If frame pointer is NOT needed,
3062 we cannot calculate the sp adjustment from frame pointer.
3063 Instead, we calculate the adjustment by local_size,
3064 out_args_size, and callee_saved_area_padding_bytes.
3065 Notice that such sp adjustment value may be out of range,
3066 so we have to deal with it as well. */
3068 /* Adjust $sp = $sp + local_size + out_args_size
3069 + callee_saved_area_padding_bytes. */
3070 sp_adjust = cfun->machine->local_size
3071 + cfun->machine->out_args_size
3072 + cfun->machine->callee_saved_area_padding_bytes;
3073 /* sp_adjust value may be out of range of the addi instruction,
3074 create alternative add behavior with TA_REGNUM if necessary,
3075 using POSITIVE value to tell that we are increasing address. */
3076 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3077 if (sp_adjust)
3079 /* Generate sp adjustment instruction
3080 if and only if sp_adjust != 0. */
3081 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3082 stack_pointer_rtx,
3083 GEN_INT (sp_adjust));
3084 /* Emit rtx into instructions list and receive INSN rtx form. */
3085 sp_adjust_insn = emit_insn (sp_adjust_insn);
3089 /* pop_insn = gen_stack_v3pop(last_regno, sp_adjust),
3090 the pattern 'stack_v3pop' is implementad in nds32.md. */
3091 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3092 pop_insn = nds32_gen_stack_v3pop (Rb, Re,
3093 GEN_INT (14), GEN_INT (0));
3095 /* Emit pop instruction. */
3096 emit_insn (pop_insn);
3100 /* ------------------------------------------------------------------------ */
3102 /* Function to test 333-form for load/store instructions.
3103 This is auxiliary extern function for auxiliary macro in nds32.h.
3104 Because it is a little complicated, we use function instead of macro. */
3105 bool
3106 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
3108 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3109 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3111 if (GET_MODE_SIZE (mode) == 4)
3112 return satisfies_constraint_Iu05 (imm);
3114 if (GET_MODE_SIZE (mode) == 2)
3115 return satisfies_constraint_Iu04 (imm);
3117 if (GET_MODE_SIZE (mode) == 1)
3118 return satisfies_constraint_Iu03 (imm);
3121 return false;
3125 /* Computing the Length of an Insn.
3126 Modifies the length assigned to instruction INSN.
3127 LEN is the initially computed length of the insn. */
3129 nds32_adjust_insn_length (rtx insn, int length)
3131 rtx src, dst;
3133 switch (recog_memoized (insn))
3135 case CODE_FOR_move_df:
3136 case CODE_FOR_move_di:
3137 /* Adjust length of movd44 to 2. */
3138 src = XEXP (PATTERN (insn), 1);
3139 dst = XEXP (PATTERN (insn), 0);
3141 if (REG_P (src)
3142 && REG_P (dst)
3143 && (REGNO (src) % 2) == 0
3144 && (REGNO (dst) % 2) == 0)
3145 length = 2;
3146 break;
3148 default:
3149 break;
3152 return length;
3156 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3158 nds32_target_alignment (rtx label)
3160 rtx insn;
3162 if (optimize_size)
3163 return 0;
3165 insn = next_active_insn (label);
3167 if (insn == 0)
3168 return 0;
3169 else if ((get_attr_length (insn) % 4) == 0)
3170 return 2;
3171 else
3172 return 0;
3175 /* ------------------------------------------------------------------------ */
3177 /* PART 5: Initialize target hook structure and definitions. */
3179 /* Controlling the Compilation Driver. */
3182 /* Run-time Target Specification. */
3185 /* Defining Data Structures for Per-function Information. */
3188 /* Storage Layout. */
3190 #undef TARGET_PROMOTE_FUNCTION_MODE
3191 #define TARGET_PROMOTE_FUNCTION_MODE \
3192 default_promote_function_mode_always_promote
3195 /* Layout of Source Language Data Types. */
3198 /* Register Usage. */
3200 /* -- Basic Characteristics of Registers. */
3202 /* -- Order of Allocation of Registers. */
3204 /* -- How Values Fit in Registers. */
3206 /* -- Handling Leaf Functions. */
3208 /* -- Registers That Form a Stack. */
3211 /* Register Classes. */
3213 #undef TARGET_CLASS_MAX_NREGS
3214 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3216 #undef TARGET_LRA_P
3217 #define TARGET_LRA_P hook_bool_void_true
3219 #undef TARGET_REGISTER_PRIORITY
3220 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3223 /* Obsolete Macros for Defining Constraints. */
3226 /* Stack Layout and Calling Conventions. */
3228 /* -- Basic Stack Layout. */
3230 /* -- Exception Handling Support. */
3232 /* -- Specifying How Stack Checking is Done. */
3234 /* -- Registers That Address the Stack Frame. */
3236 /* -- Eliminating Frame Pointer and Arg Pointer. */
3238 #undef TARGET_CAN_ELIMINATE
3239 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3241 /* -- Passing Function Arguments on the Stack. */
3243 /* -- Passing Arguments in Registers. */
3245 #undef TARGET_FUNCTION_ARG
3246 #define TARGET_FUNCTION_ARG nds32_function_arg
3248 #undef TARGET_FUNCTION_ARG_ADVANCE
3249 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3251 #undef TARGET_FUNCTION_ARG_BOUNDARY
3252 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3254 /* -- How Scalar Function Values Are Returned. */
3256 #undef TARGET_FUNCTION_VALUE
3257 #define TARGET_FUNCTION_VALUE nds32_function_value
3259 #undef TARGET_LIBCALL_VALUE
3260 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3262 #undef TARGET_FUNCTION_VALUE_REGNO_P
3263 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3265 /* -- How Large Values Are Returned. */
3267 /* -- Caller-Saves Register Allocation. */
3269 /* -- Function Entry and Exit. */
3271 #undef TARGET_ASM_FUNCTION_PROLOGUE
3272 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3274 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3275 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3277 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3278 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3280 #undef TARGET_ASM_FUNCTION_EPILOGUE
3281 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3283 #undef TARGET_ASM_OUTPUT_MI_THUNK
3284 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3286 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3287 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3289 /* -- Generating Code for Profiling. */
3291 /* -- Permitting tail calls. */
3293 #undef TARGET_WARN_FUNC_RETURN
3294 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3296 /* Stack smashing protection. */
3299 /* Implementing the Varargs Macros. */
3301 #undef TARGET_STRICT_ARGUMENT_NAMING
3302 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3305 /* Trampolines for Nested Functions. */
3307 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3308 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3310 #undef TARGET_TRAMPOLINE_INIT
3311 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3314 /* Implicit Calls to Library Routines. */
3317 /* Addressing Modes. */
3319 #undef TARGET_LEGITIMATE_ADDRESS_P
3320 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3323 /* Anchored Addresses. */
3326 /* Condition Code Status. */
3328 /* -- Representation of condition codes using (cc0). */
3330 /* -- Representation of condition codes using registers. */
3332 /* -- Macros to control conditional execution. */
3335 /* Describing Relative Costs of Operations. */
3337 #undef TARGET_REGISTER_MOVE_COST
3338 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3340 #undef TARGET_MEMORY_MOVE_COST
3341 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3343 #undef TARGET_RTX_COSTS
3344 #define TARGET_RTX_COSTS nds32_rtx_costs
3346 #undef TARGET_ADDRESS_COST
3347 #define TARGET_ADDRESS_COST nds32_address_cost
3350 /* Adjusting the Instruction Scheduler. */
3353 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3356 /* Position Independent Code. */
3359 /* Defining the Output Assembler Language. */
3361 /* -- The Overall Framework of an Assembler File. */
3363 #undef TARGET_ASM_FILE_START
3364 #define TARGET_ASM_FILE_START nds32_asm_file_start
3365 #undef TARGET_ASM_FILE_END
3366 #define TARGET_ASM_FILE_END nds32_asm_file_end
3368 /* -- Output of Data. */
3370 #undef TARGET_ASM_ALIGNED_HI_OP
3371 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3373 #undef TARGET_ASM_ALIGNED_SI_OP
3374 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3376 /* -- Output of Uninitialized Variables. */
3378 /* -- Output and Generation of Labels. */
3380 #undef TARGET_ASM_GLOBALIZE_LABEL
3381 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3383 /* -- How Initialization Functions Are Handled. */
3385 /* -- Macros Controlling Initialization Routines. */
3387 /* -- Output of Assembler Instructions. */
3389 #undef TARGET_PRINT_OPERAND
3390 #define TARGET_PRINT_OPERAND nds32_print_operand
3391 #undef TARGET_PRINT_OPERAND_ADDRESS
3392 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3394 /* -- Output of Dispatch Tables. */
3396 /* -- Assembler Commands for Exception Regions. */
3398 /* -- Assembler Commands for Alignment. */
3401 /* Controlling Debugging Information Format. */
3403 /* -- Macros Affecting All Debugging Formats. */
3405 /* -- Specific Options for DBX Output. */
3407 /* -- Open-Ended Hooks for DBX Format. */
3409 /* -- File Names in DBX Format. */
3411 /* -- Macros for SDB and DWARF Output. */
3413 /* -- Macros for VMS Debug Format. */
3416 /* Cross Compilation and Floating Point. */
3419 /* Mode Switching Instructions. */
3422 /* Defining target-specific uses of __attribute__. */
3424 #undef TARGET_ATTRIBUTE_TABLE
3425 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3427 #undef TARGET_MERGE_DECL_ATTRIBUTES
3428 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3430 #undef TARGET_INSERT_ATTRIBUTES
3431 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3433 #undef TARGET_OPTION_PRAGMA_PARSE
3434 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3436 #undef TARGET_OPTION_OVERRIDE
3437 #define TARGET_OPTION_OVERRIDE nds32_option_override
3440 /* Emulating TLS. */
3443 /* Defining coprocessor specifics for MIPS targets. */
3446 /* Parameters for Precompiled Header Validity Checking. */
3449 /* C++ ABI parameters. */
3452 /* Adding support for named address spaces. */
3455 /* Miscellaneous Parameters. */
3457 #undef TARGET_INIT_BUILTINS
3458 #define TARGET_INIT_BUILTINS nds32_init_builtins
3460 #undef TARGET_EXPAND_BUILTIN
3461 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3464 /* ------------------------------------------------------------------------ */
3466 /* Initialize the GCC target structure. */
3468 struct gcc_target targetm = TARGET_INITIALIZER;
3470 /* ------------------------------------------------------------------------ */