[NDS32] Remove unused variables.
[official-gcc.git] / gcc / config / nds32 / nds32.c
blob1bb8c4c9cc52c392eb09ceafe465d57de86d2720
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 and there
219 is no outgoing size.
220 condition 3: There is no local_size, which means
221 we do not need to adjust $sp. */
222 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl))
223 || (cfun->machine->callee_saved_regs_first_regno == SP_REGNUM
224 && cfun->machine->callee_saved_regs_last_regno == SP_REGNUM
225 && !df_regs_ever_live_p (FP_REGNUM)
226 && !df_regs_ever_live_p (LP_REGNUM)
227 && cfun->machine->local_size == 0))
229 /* Set this function 'naked_p' and other functions can check this flag.
230 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
231 callee-saved, local size, and outgoing size.
232 The varargs space and ret instruction may still present in
233 the prologue/epilogue expanding. */
234 cfun->machine->naked_p = 1;
236 /* No need to save $fp, $gp, and $lp.
237 We should set these value to be zero
238 so that nds32_initial_elimination_offset() can work properly. */
239 cfun->machine->fp_size = 0;
240 cfun->machine->gp_size = 0;
241 cfun->machine->lp_size = 0;
243 /* If stack usage computation is required,
244 we need to provide the static stack size. */
245 if (flag_stack_usage_info)
246 current_function_static_stack_size = 0;
248 /* No need to do following adjustment, return immediately. */
249 return;
252 /* Adjustment for v3push instructions:
253 If we are using v3push (push25/pop25) instructions,
254 we need to make sure Rb is $r6 and Re is
255 located on $r6, $r8, $r10, or $r14.
256 Some results above will be discarded and recomputed.
257 Note that it is only available under V3/V3M ISA and we
258 DO NOT setup following stuff for isr or variadic function. */
259 if (TARGET_V3PUSH
260 && !nds32_isr_function_p (current_function_decl)
261 && (cfun->machine->va_args_size == 0))
263 /* Recompute:
264 cfun->machine->fp_size
265 cfun->machine->gp_size
266 cfun->machine->lp_size
267 cfun->machine->callee_saved_regs_first_regno
268 cfun->machine->callee_saved_regs_last_regno */
270 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
271 cfun->machine->fp_size = 4;
272 cfun->machine->gp_size = 4;
273 cfun->machine->lp_size = 4;
275 /* Remember to set Rb = $r6. */
276 cfun->machine->callee_saved_regs_first_regno = 6;
278 if (cfun->machine->callee_saved_regs_last_regno <= 6)
280 /* Re = $r6 */
281 cfun->machine->callee_saved_regs_last_regno = 6;
283 else if (cfun->machine->callee_saved_regs_last_regno <= 8)
285 /* Re = $r8 */
286 cfun->machine->callee_saved_regs_last_regno = 8;
288 else if (cfun->machine->callee_saved_regs_last_regno <= 10)
290 /* Re = $r10 */
291 cfun->machine->callee_saved_regs_last_regno = 10;
293 else if (cfun->machine->callee_saved_regs_last_regno <= 14)
295 /* Re = $r14 */
296 cfun->machine->callee_saved_regs_last_regno = 14;
298 else if (cfun->machine->callee_saved_regs_last_regno == SP_REGNUM)
300 /* If last_regno is SP_REGNUM, which means
301 it is never changed, so set it to Re = $r6. */
302 cfun->machine->callee_saved_regs_last_regno = 6;
304 else
306 /* The program flow should not go here. */
307 gcc_unreachable ();
311 /* We have correctly set callee_saved_regs_first_regno
312 and callee_saved_regs_last_regno.
313 Initially, the callee_saved_regs_size is supposed to be 0.
314 As long as callee_saved_regs_last_regno is not SP_REGNUM,
315 we can update callee_saved_regs_size with new size. */
316 if (cfun->machine->callee_saved_regs_last_regno != SP_REGNUM)
318 /* Compute pushed size of callee-saved registers. */
319 cfun->machine->callee_saved_regs_size
320 = 4 * (cfun->machine->callee_saved_regs_last_regno
321 - cfun->machine->callee_saved_regs_first_regno
322 + 1);
325 /* Important: We need to make sure that
326 (va_args_size + fp_size + gp_size
327 + lp_size + callee_saved_regs_size)
328 is 8-byte alignment.
329 If it is not, calculate the padding bytes. */
330 block_size = cfun->machine->va_args_size
331 + cfun->machine->fp_size
332 + cfun->machine->gp_size
333 + cfun->machine->lp_size
334 + cfun->machine->callee_saved_regs_size;
335 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size))
337 cfun->machine->callee_saved_area_padding_bytes
338 = NDS32_ROUND_UP_DOUBLE_WORD (block_size) - block_size;
341 /* If stack usage computation is required,
342 we need to provide the static stack size. */
343 if (flag_stack_usage_info)
345 current_function_static_stack_size
346 = NDS32_ROUND_UP_DOUBLE_WORD (block_size)
347 + cfun->machine->local_size
348 + cfun->machine->out_args_size;
352 /* Function to create a parallel rtx pattern
353 which presents stack push multiple behavior.
354 The overall concept are:
355 "push registers to memory",
356 "adjust stack pointer". */
357 static void
358 nds32_emit_stack_push_multiple (rtx Rb, rtx Re, rtx En4)
360 int regno;
361 int extra_count;
362 int num_use_regs;
363 int par_index;
364 int offset;
365 int save_fp, save_gp, save_lp;
367 rtx reg;
368 rtx mem;
369 rtx push_rtx;
370 rtx adjust_sp_rtx;
371 rtx parallel_insn;
373 /* We need to provide a customized rtx which contains
374 necessary information for data analysis,
375 so we create a parallel rtx like this:
376 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
377 (reg:SI Rb))
378 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
379 (reg:SI Rb+1))
381 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
382 (reg:SI Re))
383 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
384 (reg:SI FP_REGNUM))
385 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
386 (reg:SI GP_REGNUM))
387 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
388 (reg:SI LP_REGNUM))
389 (set (reg:SI SP_REGNUM)
390 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
392 /* Determine whether we need to save $fp, $gp, or $lp. */
393 save_fp = INTVAL (En4) & 0x8;
394 save_gp = INTVAL (En4) & 0x4;
395 save_lp = INTVAL (En4) & 0x2;
397 /* Calculate the number of registers that will be pushed. */
398 extra_count = 0;
399 if (save_fp)
400 extra_count++;
401 if (save_gp)
402 extra_count++;
403 if (save_lp)
404 extra_count++;
405 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
406 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
407 num_use_regs = extra_count;
408 else
409 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
411 /* In addition to used registers,
412 we need one more space for (set sp sp-x) rtx. */
413 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
414 rtvec_alloc (num_use_regs + 1));
415 par_index = 0;
417 /* Initialize offset and start to create push behavior. */
418 offset = -(num_use_regs * 4);
420 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
421 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
423 /* Rb and Re may be SP_REGNUM.
424 We need to break this loop immediately. */
425 if (regno == SP_REGNUM)
426 break;
428 reg = gen_rtx_REG (SImode, regno);
429 mem = gen_frame_mem (SImode, plus_constant (Pmode,
430 stack_pointer_rtx,
431 offset));
432 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
433 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
434 RTX_FRAME_RELATED_P (push_rtx) = 1;
435 offset = offset + 4;
436 par_index++;
439 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
440 if (save_fp)
442 reg = gen_rtx_REG (SImode, FP_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 (save_gp)
454 reg = gen_rtx_REG (SImode, GP_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++;
464 if (save_lp)
466 reg = gen_rtx_REG (SImode, LP_REGNUM);
467 mem = gen_frame_mem (SImode, plus_constant (Pmode,
468 stack_pointer_rtx,
469 offset));
470 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
471 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
472 RTX_FRAME_RELATED_P (push_rtx) = 1;
473 offset = offset + 4;
474 par_index++;
477 /* Create (set sp sp-x). */
479 /* We need to re-calculate the offset value again for adjustment. */
480 offset = -(num_use_regs * 4);
481 adjust_sp_rtx
482 = gen_rtx_SET (VOIDmode,
483 stack_pointer_rtx,
484 plus_constant (Pmode, stack_pointer_rtx, offset));
485 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
486 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
488 parallel_insn = emit_insn (parallel_insn);
490 /* The insn rtx 'parallel_insn' will change frame layout.
491 We need to use RTX_FRAME_RELATED_P so that GCC is able to
492 generate CFI (Call Frame Information) stuff. */
493 RTX_FRAME_RELATED_P (parallel_insn) = 1;
496 /* Function to create a parallel rtx pattern
497 which presents stack pop multiple behavior.
498 The overall concept are:
499 "pop registers from memory",
500 "adjust stack pointer". */
501 static void
502 nds32_emit_stack_pop_multiple (rtx Rb, rtx Re, rtx En4)
504 int regno;
505 int extra_count;
506 int num_use_regs;
507 int par_index;
508 int offset;
509 int save_fp, save_gp, save_lp;
511 rtx reg;
512 rtx mem;
513 rtx pop_rtx;
514 rtx adjust_sp_rtx;
515 rtx parallel_insn;
516 rtx dwarf = NULL_RTX;
518 /* We need to provide a customized rtx which contains
519 necessary information for data analysis,
520 so we create a parallel rtx like this:
521 (parallel [(set (reg:SI Rb)
522 (mem (reg:SI SP_REGNUM)))
523 (set (reg:SI Rb+1)
524 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
526 (set (reg:SI Re)
527 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
528 (set (reg:SI FP_REGNUM)
529 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
530 (set (reg:SI GP_REGNUM)
531 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
532 (set (reg:SI LP_REGNUM)
533 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
534 (set (reg:SI SP_REGNUM)
535 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
537 /* Determine whether we need to restore $fp, $gp, or $lp. */
538 save_fp = INTVAL (En4) & 0x8;
539 save_gp = INTVAL (En4) & 0x4;
540 save_lp = INTVAL (En4) & 0x2;
542 /* Calculate the number of registers that will be poped. */
543 extra_count = 0;
544 if (save_fp)
545 extra_count++;
546 if (save_gp)
547 extra_count++;
548 if (save_lp)
549 extra_count++;
550 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
551 if (REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM)
552 num_use_regs = extra_count;
553 else
554 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + extra_count;
556 /* In addition to used registers,
557 we need one more space for (set sp sp+x) rtx. */
558 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
559 rtvec_alloc (num_use_regs + 1));
560 par_index = 0;
562 /* Initialize offset and start to create pop behavior. */
563 offset = 0;
565 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
566 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
568 /* Rb and Re may be SP_REGNUM.
569 We need to break this loop immediately. */
570 if (regno == SP_REGNUM)
571 break;
573 reg = gen_rtx_REG (SImode, regno);
574 mem = gen_frame_mem (SImode, plus_constant (Pmode,
575 stack_pointer_rtx,
576 offset));
577 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
578 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
579 RTX_FRAME_RELATED_P (pop_rtx) = 1;
580 offset = offset + 4;
581 par_index++;
583 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
586 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
587 if (save_fp)
589 reg = gen_rtx_REG (SImode, FP_REGNUM);
590 mem = gen_frame_mem (SImode, plus_constant (Pmode,
591 stack_pointer_rtx,
592 offset));
593 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
594 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
595 RTX_FRAME_RELATED_P (pop_rtx) = 1;
596 offset = offset + 4;
597 par_index++;
599 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
601 if (save_gp)
603 reg = gen_rtx_REG (SImode, GP_REGNUM);
604 mem = gen_frame_mem (SImode, plus_constant (Pmode,
605 stack_pointer_rtx,
606 offset));
607 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
608 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
609 RTX_FRAME_RELATED_P (pop_rtx) = 1;
610 offset = offset + 4;
611 par_index++;
613 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
615 if (save_lp)
617 reg = gen_rtx_REG (SImode, LP_REGNUM);
618 mem = gen_frame_mem (SImode, plus_constant (Pmode,
619 stack_pointer_rtx,
620 offset));
621 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
622 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
623 RTX_FRAME_RELATED_P (pop_rtx) = 1;
624 offset = offset + 4;
625 par_index++;
627 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
630 /* Create (set sp sp+x). */
632 /* The offset value is already in place. No need to re-calculate it. */
633 adjust_sp_rtx
634 = gen_rtx_SET (VOIDmode,
635 stack_pointer_rtx,
636 plus_constant (Pmode, stack_pointer_rtx, offset));
637 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
639 /* Tell gcc we adjust SP in this insn. */
640 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
642 parallel_insn = emit_insn (parallel_insn);
644 /* The insn rtx 'parallel_insn' will change frame layout.
645 We need to use RTX_FRAME_RELATED_P so that GCC is able to
646 generate CFI (Call Frame Information) stuff. */
647 RTX_FRAME_RELATED_P (parallel_insn) = 1;
649 /* Add CFI info by manual. */
650 REG_NOTES (parallel_insn) = dwarf;
653 /* Function to create a parallel rtx pattern
654 which presents stack v3push behavior.
655 The overall concept are:
656 "push registers to memory",
657 "adjust stack pointer". */
658 static void
659 nds32_emit_stack_v3push (rtx Rb,
660 rtx Re,
661 rtx En4 ATTRIBUTE_UNUSED,
662 rtx imm8u)
664 int regno;
665 int num_use_regs;
666 int par_index;
667 int offset;
669 rtx reg;
670 rtx mem;
671 rtx push_rtx;
672 rtx adjust_sp_rtx;
673 rtx parallel_insn;
675 /* We need to provide a customized rtx which contains
676 necessary information for data analysis,
677 so we create a parallel rtx like this:
678 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
679 (reg:SI Rb))
680 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
681 (reg:SI Rb+1))
683 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
684 (reg:SI Re))
685 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
686 (reg:SI FP_REGNUM))
687 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
688 (reg:SI GP_REGNUM))
689 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
690 (reg:SI LP_REGNUM))
691 (set (reg:SI SP_REGNUM)
692 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
694 /* Calculate the number of registers that will be pushed.
695 Since $fp, $gp, and $lp is always pushed with v3push instruction,
696 we need to count these three registers.
697 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
698 So there is no need to worry about Rb=Re=SP_REGNUM case. */
699 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
701 /* In addition to used registers,
702 we need one more space for (set sp sp-x-imm8u) rtx. */
703 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
704 rtvec_alloc (num_use_regs + 1));
705 par_index = 0;
707 /* Initialize offset and start to create push behavior. */
708 offset = -(num_use_regs * 4);
710 /* Create (set mem regX) from Rb, Rb+1 up to Re.
711 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
712 So there is no need to worry about Rb=Re=SP_REGNUM case. */
713 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
715 reg = gen_rtx_REG (SImode, regno);
716 mem = gen_frame_mem (SImode, plus_constant (Pmode,
717 stack_pointer_rtx,
718 offset));
719 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
720 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
721 RTX_FRAME_RELATED_P (push_rtx) = 1;
722 offset = offset + 4;
723 par_index++;
726 /* Create (set mem fp). */
727 reg = gen_rtx_REG (SImode, FP_REGNUM);
728 mem = gen_frame_mem (SImode, plus_constant (Pmode,
729 stack_pointer_rtx,
730 offset));
731 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
732 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
733 RTX_FRAME_RELATED_P (push_rtx) = 1;
734 offset = offset + 4;
735 par_index++;
736 /* Create (set mem gp). */
737 reg = gen_rtx_REG (SImode, GP_REGNUM);
738 mem = gen_frame_mem (SImode, plus_constant (Pmode,
739 stack_pointer_rtx,
740 offset));
741 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
742 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
743 RTX_FRAME_RELATED_P (push_rtx) = 1;
744 offset = offset + 4;
745 par_index++;
746 /* Create (set mem lp). */
747 reg = gen_rtx_REG (SImode, LP_REGNUM);
748 mem = gen_frame_mem (SImode, plus_constant (Pmode,
749 stack_pointer_rtx,
750 offset));
751 push_rtx = gen_rtx_SET (VOIDmode, mem, reg);
752 XVECEXP (parallel_insn, 0, par_index) = push_rtx;
753 RTX_FRAME_RELATED_P (push_rtx) = 1;
754 offset = offset + 4;
755 par_index++;
757 /* Create (set sp sp-x-imm8u). */
759 /* We need to re-calculate the offset value again for adjustment. */
760 offset = -(num_use_regs * 4);
761 adjust_sp_rtx
762 = gen_rtx_SET (VOIDmode,
763 stack_pointer_rtx,
764 plus_constant (Pmode,
765 stack_pointer_rtx,
766 offset - INTVAL (imm8u)));
767 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
768 RTX_FRAME_RELATED_P (adjust_sp_rtx) = 1;
770 parallel_insn = emit_insn (parallel_insn);
772 /* The insn rtx 'parallel_insn' will change frame layout.
773 We need to use RTX_FRAME_RELATED_P so that GCC is able to
774 generate CFI (Call Frame Information) stuff. */
775 RTX_FRAME_RELATED_P (parallel_insn) = 1;
778 /* Function to create a parallel rtx pattern
779 which presents stack v3pop behavior.
780 The overall concept are:
781 "pop registers from memory",
782 "adjust stack pointer". */
783 static void
784 nds32_emit_stack_v3pop (rtx Rb,
785 rtx Re,
786 rtx En4 ATTRIBUTE_UNUSED,
787 rtx imm8u)
789 int regno;
790 int num_use_regs;
791 int par_index;
792 int offset;
794 rtx reg;
795 rtx mem;
796 rtx pop_rtx;
797 rtx adjust_sp_rtx;
798 rtx parallel_insn;
799 rtx dwarf = NULL_RTX;
801 /* We need to provide a customized rtx which contains
802 necessary information for data analysis,
803 so we create a parallel rtx like this:
804 (parallel [(set (reg:SI Rb)
805 (mem (reg:SI SP_REGNUM)))
806 (set (reg:SI Rb+1)
807 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
809 (set (reg:SI Re)
810 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
811 (set (reg:SI FP_REGNUM)
812 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
813 (set (reg:SI GP_REGNUM)
814 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
815 (set (reg:SI LP_REGNUM)
816 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
817 (set (reg:SI SP_REGNUM)
818 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
820 /* Calculate the number of registers that will be poped.
821 Since $fp, $gp, and $lp is always poped with v3pop instruction,
822 we need to count these three registers.
823 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
824 So there is no need to worry about Rb=Re=SP_REGNUM case. */
825 num_use_regs = REGNO (Re) - REGNO (Rb) + 1 + 3;
827 /* In addition to used registers,
828 we need one more space for (set sp sp+x+imm8u) rtx. */
829 parallel_insn = gen_rtx_PARALLEL (VOIDmode,
830 rtvec_alloc (num_use_regs + 1));
831 par_index = 0;
833 /* Initialize offset and start to create pop behavior. */
834 offset = 0;
836 /* Create (set regX mem) from Rb, Rb+1 up to Re.
837 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
838 So there is no need to worry about Rb=Re=SP_REGNUM case. */
839 for (regno = REGNO (Rb); regno <= (int) REGNO (Re); regno++)
841 reg = gen_rtx_REG (SImode, regno);
842 mem = gen_frame_mem (SImode, plus_constant (Pmode,
843 stack_pointer_rtx,
844 offset));
845 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
846 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
847 RTX_FRAME_RELATED_P (pop_rtx) = 1;
848 offset = offset + 4;
849 par_index++;
851 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
854 /* Create (set fp mem). */
855 reg = gen_rtx_REG (SImode, FP_REGNUM);
856 mem = gen_frame_mem (SImode, plus_constant (Pmode,
857 stack_pointer_rtx,
858 offset));
859 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
860 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
861 RTX_FRAME_RELATED_P (pop_rtx) = 1;
862 offset = offset + 4;
863 par_index++;
864 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
866 /* Create (set gp mem). */
867 reg = gen_rtx_REG (SImode, GP_REGNUM);
868 mem = gen_frame_mem (SImode, plus_constant (Pmode,
869 stack_pointer_rtx,
870 offset));
871 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
872 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
873 RTX_FRAME_RELATED_P (pop_rtx) = 1;
874 offset = offset + 4;
875 par_index++;
876 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
878 /* Create (set lp mem ). */
879 reg = gen_rtx_REG (SImode, LP_REGNUM);
880 mem = gen_frame_mem (SImode, plus_constant (Pmode,
881 stack_pointer_rtx,
882 offset));
883 pop_rtx = gen_rtx_SET (VOIDmode, reg, mem);
884 XVECEXP (parallel_insn, 0, par_index) = pop_rtx;
885 RTX_FRAME_RELATED_P (pop_rtx) = 1;
886 offset = offset + 4;
887 par_index++;
888 dwarf = alloc_reg_note (REG_CFA_RESTORE, reg, dwarf);
890 /* Create (set sp sp+x+imm8u). */
892 /* The offset value is already in place. No need to re-calculate it. */
893 adjust_sp_rtx
894 = gen_rtx_SET (VOIDmode,
895 stack_pointer_rtx,
896 plus_constant (Pmode,
897 stack_pointer_rtx,
898 offset + INTVAL (imm8u)));
899 XVECEXP (parallel_insn, 0, par_index) = adjust_sp_rtx;
901 /* Tell gcc we adjust SP in this insn. */
902 dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, copy_rtx (adjust_sp_rtx), dwarf);
904 parallel_insn = emit_insn (parallel_insn);
906 /* The insn rtx 'parallel_insn' will change frame layout.
907 We need to use RTX_FRAME_RELATED_P so that GCC is able to
908 generate CFI (Call Frame Information) stuff. */
909 RTX_FRAME_RELATED_P (parallel_insn) = 1;
911 /* Add CFI info by manual. */
912 REG_NOTES (parallel_insn) = dwarf;
915 /* Function that may creates more instructions
916 for large value on adjusting stack pointer.
918 In nds32 target, 'addi' can be used for stack pointer
919 adjustment in prologue/epilogue stage.
920 However, sometimes there are too many local variables so that
921 the adjustment value is not able to be fit in the 'addi' instruction.
922 One solution is to move value into a register
923 and then use 'add' instruction.
924 In practice, we use TA_REGNUM ($r15) to accomplish this purpose.
925 Also, we need to return zero for sp adjustment so that
926 proglogue/epilogue knows there is no need to create 'addi' instruction. */
927 static int
928 nds32_force_addi_stack_int (int full_value)
930 int adjust_value;
932 rtx tmp_reg;
933 rtx sp_adjust_insn;
935 if (!satisfies_constraint_Is15 (GEN_INT (full_value)))
937 /* The value is not able to fit in single addi instruction.
938 Create more instructions of moving value into a register
939 and then add stack pointer with it. */
941 /* $r15 is going to be temporary register to hold the value. */
942 tmp_reg = gen_rtx_REG (SImode, TA_REGNUM);
944 /* Create one more instruction to move value
945 into the temporary register. */
946 emit_move_insn (tmp_reg, GEN_INT (full_value));
948 /* Create new 'add' rtx. */
949 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
950 stack_pointer_rtx,
951 tmp_reg);
952 /* Emit rtx into insn list and receive its transformed insn rtx. */
953 sp_adjust_insn = emit_insn (sp_adjust_insn);
955 /* At prologue, we need to tell GCC that this is frame related insn,
956 so that we can consider this instruction to output debug information.
957 If full_value is NEGATIVE, it means this function
958 is invoked by expand_prologue. */
959 if (full_value < 0)
961 /* Because (tmp_reg <- full_value) may be split into two
962 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
963 We need to construct another (sp <- sp + full_value)
964 and then insert it into sp_adjust_insn's reg note to
965 represent a frame related expression.
966 GCC knows how to refer it and output debug information. */
968 rtx plus_rtx;
969 rtx set_rtx;
971 plus_rtx = plus_constant (Pmode, stack_pointer_rtx, full_value);
972 set_rtx = gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_rtx);
973 add_reg_note (sp_adjust_insn, REG_FRAME_RELATED_EXPR, set_rtx);
975 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
978 /* We have used alternative way to adjust stack pointer value.
979 Return zero so that prologue/epilogue
980 will not generate other instructions. */
981 return 0;
983 else
985 /* The value is able to fit in addi instruction.
986 However, remember to make it to be positive value
987 because we want to return 'adjustment' result. */
988 adjust_value = (full_value < 0) ? (-full_value) : (full_value);
990 return adjust_value;
994 /* Return true if MODE/TYPE need double word alignment. */
995 static bool
996 nds32_needs_double_word_align (enum machine_mode mode, const_tree type)
998 unsigned int align;
1000 /* Pick up the alignment according to the mode or type. */
1001 align = NDS32_MODE_TYPE_ALIGN (mode, type);
1003 return (align > PARM_BOUNDARY);
1006 /* Return true if FUNC is a naked function. */
1007 static bool
1008 nds32_naked_function_p (tree func)
1010 tree t;
1012 if (TREE_CODE (func) != FUNCTION_DECL)
1013 abort ();
1015 t = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
1017 return (t != NULL_TREE);
1020 /* Function that check if 'X' is a valid address register.
1021 The variable 'STRICT' is very important to
1022 make decision for register number.
1024 STRICT : true
1025 => We are in reload pass or after reload pass.
1026 The register number should be strictly limited in general registers.
1028 STRICT : false
1029 => Before reload pass, we are free to use any register number. */
1030 static bool
1031 nds32_address_register_rtx_p (rtx x, bool strict)
1033 int regno;
1035 if (GET_CODE (x) != REG)
1036 return false;
1038 regno = REGNO (x);
1040 if (strict)
1041 return REGNO_OK_FOR_BASE_P (regno);
1042 else
1043 return true;
1046 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1048 OUTER_MODE : Machine mode of outer address rtx.
1049 INDEX : Check if this rtx is valid to be a index for address.
1050 STRICT : If it is true, we are in reload pass or after reload pass. */
1051 static bool
1052 nds32_legitimate_index_p (enum machine_mode outer_mode,
1053 rtx index,
1054 bool strict)
1056 int regno;
1057 rtx op0;
1058 rtx op1;
1060 switch (GET_CODE (index))
1062 case REG:
1063 regno = REGNO (index);
1064 /* If we are in reload pass or after reload pass,
1065 we need to limit it to general register. */
1066 if (strict)
1067 return REGNO_OK_FOR_INDEX_P (regno);
1068 else
1069 return true;
1071 case CONST_INT:
1072 /* The alignment of the integer value is determined by 'outer_mode'. */
1073 if (GET_MODE_SIZE (outer_mode) == 1)
1075 /* Further check if the value is legal for the 'outer_mode'. */
1076 if (!satisfies_constraint_Is15 (index))
1077 return false;
1079 /* Pass all test, the value is valid, return true. */
1080 return true;
1082 if (GET_MODE_SIZE (outer_mode) == 2
1083 && NDS32_HALF_WORD_ALIGN_P (INTVAL (index)))
1085 /* Further check if the value is legal for the 'outer_mode'. */
1086 if (!satisfies_constraint_Is16 (index))
1087 return false;
1089 /* Pass all test, the value is valid, return true. */
1090 return true;
1092 if (GET_MODE_SIZE (outer_mode) == 4
1093 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1095 /* Further check if the value is legal for the 'outer_mode'. */
1096 if (!satisfies_constraint_Is17 (index))
1097 return false;
1099 /* Pass all test, the value is valid, return true. */
1100 return true;
1102 if (GET_MODE_SIZE (outer_mode) == 8
1103 && NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index)))
1105 /* Further check if the value is legal for the 'outer_mode'. */
1106 if (!satisfies_constraint_Is17 (gen_int_mode (INTVAL (index) + 4,
1107 SImode)))
1108 return false;
1110 /* Pass all test, the value is valid, return true. */
1111 return true;
1114 return false;
1116 case MULT:
1117 op0 = XEXP (index, 0);
1118 op1 = XEXP (index, 1);
1120 if (REG_P (op0) && CONST_INT_P (op1))
1122 int multiplier;
1123 multiplier = INTVAL (op1);
1125 /* We only allow (mult reg const_int_1)
1126 or (mult reg const_int_2) or (mult reg const_int_4). */
1127 if (multiplier != 1 && multiplier != 2 && multiplier != 4)
1128 return false;
1130 regno = REGNO (op0);
1131 /* Limit it in general registers if we are
1132 in reload pass or after reload pass. */
1133 if(strict)
1134 return REGNO_OK_FOR_INDEX_P (regno);
1135 else
1136 return true;
1139 return false;
1141 case ASHIFT:
1142 op0 = XEXP (index, 0);
1143 op1 = XEXP (index, 1);
1145 if (REG_P (op0) && CONST_INT_P (op1))
1147 int sv;
1148 /* op1 is already the sv value for use to do left shift. */
1149 sv = INTVAL (op1);
1151 /* We only allow (ashift reg const_int_0)
1152 or (ashift reg const_int_1) or (ashift reg const_int_2). */
1153 if (sv != 0 && sv != 1 && sv !=2)
1154 return false;
1156 regno = REGNO (op0);
1157 /* Limit it in general registers if we are
1158 in reload pass or after reload pass. */
1159 if(strict)
1160 return REGNO_OK_FOR_INDEX_P (regno);
1161 else
1162 return true;
1165 return false;
1167 default:
1168 return false;
1172 /* ------------------------------------------------------------------------ */
1174 /* PART 3: Implement target hook stuff definitions. */
1176 /* Register Classes. */
1178 static unsigned char
1179 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED,
1180 enum machine_mode mode)
1182 /* Return the maximum number of consecutive registers
1183 needed to represent "mode" in a register of "rclass". */
1184 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1187 static int
1188 nds32_register_priority (int hard_regno)
1190 /* Encourage to use r0-r7 for LRA when optimize for size. */
1191 if (optimize_size && hard_regno < 8)
1192 return 4;
1193 return 3;
1197 /* Stack Layout and Calling Conventions. */
1199 /* There are three kinds of pointer concepts using in GCC compiler:
1201 frame pointer: A pointer to the first location of local variables.
1202 stack pointer: A pointer to the top of a stack frame.
1203 argument pointer: A pointer to the incoming arguments.
1205 In nds32 target calling convention, we are using 8-byte alignment.
1206 Besides, we would like to have each stack frame of a function includes:
1208 [Block A]
1209 1. previous hard frame pointer
1210 2. return address
1211 3. callee-saved registers
1212 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1213 and save it at
1214 cfun->machine->callee_saved_area_padding_bytes)
1216 [Block B]
1217 1. local variables
1218 2. spilling location
1219 3. <padding bytes> (it will be calculated by GCC itself)
1220 4. incoming arguments
1221 5. <padding bytes> (it will be calculated by GCC itself)
1223 [Block C]
1224 1. <padding bytes> (it will be calculated by GCC itself)
1225 2. outgoing arguments
1227 We 'wrap' these blocks together with
1228 hard frame pointer ($r28) and stack pointer ($r31).
1229 By applying the basic frame/stack/argument pointers concept,
1230 the layout of a stack frame shoule be like this:
1233 old stack pointer -> ----
1234 | | \
1235 | | saved arguments for
1236 | | vararg functions
1237 | | /
1238 hard frame pointer -> --
1239 & argument pointer | | \
1240 | | previous hardware frame pointer
1241 | | return address
1242 | | callee-saved registers
1243 | | /
1244 frame pointer -> --
1245 | | \
1246 | | local variables
1247 | | and incoming arguments
1248 | | /
1250 | | \
1251 | | outgoing
1252 | | arguments
1253 | | /
1254 stack pointer -> ----
1256 $SFP and $AP are used to represent frame pointer and arguments pointer,
1257 which will be both eliminated as hard frame pointer. */
1259 /* -- Eliminating Frame Pointer and Arg Pointer. */
1261 static bool
1262 nds32_can_eliminate (const int from_reg, const int to_reg)
1264 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1265 return true;
1267 if (from_reg == ARG_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1268 return true;
1270 if (from_reg == FRAME_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
1271 return true;
1273 if (from_reg == FRAME_POINTER_REGNUM && to_reg == HARD_FRAME_POINTER_REGNUM)
1274 return true;
1276 return false;
1279 /* -- Passing Arguments in Registers. */
1281 static rtx
1282 nds32_function_arg (cumulative_args_t ca, enum machine_mode mode,
1283 const_tree type, bool named)
1285 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1287 /* The last time this hook is called,
1288 it is called with MODE == VOIDmode. */
1289 if (mode == VOIDmode)
1290 return NULL_RTX;
1292 /* For nameless arguments, they are passed on the stack. */
1293 if (!named)
1294 return NULL_RTX;
1296 /* If there are still registers available, return it. */
1297 if (NDS32_ARG_PASS_IN_REG_P (cum->reg_offset, mode, type))
1299 /* Pick up the next available register number. */
1300 unsigned int regno;
1302 regno = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type);
1303 return gen_rtx_REG (mode, regno);
1305 else
1307 /* No register available, return NULL_RTX.
1308 The compiler will use stack to pass argument instead. */
1309 return NULL_RTX;
1313 static void
1314 nds32_function_arg_advance (cumulative_args_t ca, enum machine_mode mode,
1315 const_tree type, bool named)
1317 CUMULATIVE_ARGS *cum = get_cumulative_args (ca);
1319 /* Advance next register for use.
1320 Only named argument could be advanced. */
1321 if (named)
1323 cum->reg_offset
1324 = NDS32_AVAILABLE_REGNUM_FOR_ARG (cum->reg_offset, mode, type)
1325 - NDS32_GPR_ARG_FIRST_REGNUM
1326 + NDS32_NEED_N_REGS_FOR_ARG (mode, type);
1330 static unsigned int
1331 nds32_function_arg_boundary (enum machine_mode mode, const_tree type)
1333 return (nds32_needs_double_word_align (mode, type)
1334 ? NDS32_DOUBLE_WORD_ALIGNMENT
1335 : PARM_BOUNDARY);
1338 /* -- How Scalar Function Values Are Returned. */
1340 static rtx
1341 nds32_function_value (const_tree ret_type,
1342 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1343 bool outgoing ATTRIBUTE_UNUSED)
1345 enum machine_mode mode;
1346 int unsignedp;
1348 mode = TYPE_MODE (ret_type);
1349 unsignedp = TYPE_UNSIGNED (ret_type);
1351 mode = promote_mode (ret_type, mode, &unsignedp);
1353 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1356 static rtx
1357 nds32_libcall_value (enum machine_mode mode,
1358 const_rtx fun ATTRIBUTE_UNUSED)
1360 return gen_rtx_REG (mode, NDS32_GPR_RET_FIRST_REGNUM);
1363 static bool
1364 nds32_function_value_regno_p (const unsigned int regno)
1366 return (regno == NDS32_GPR_RET_FIRST_REGNUM);
1369 /* -- Function Entry and Exit. */
1371 /* The content produced from this function
1372 will be placed before prologue body. */
1373 static void
1374 nds32_asm_function_prologue (FILE *file,
1375 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1377 int r;
1378 const char *func_name;
1379 tree attrs;
1380 tree name;
1382 /* All stack frame information is supposed to be
1383 already computed when expanding prologue.
1384 The result is in cfun->machine.
1385 DO NOT call nds32_compute_stack_frame() here
1386 because it may corrupt the essential information. */
1388 fprintf (file, "\t! BEGIN PROLOGUE\n");
1389 fprintf (file, "\t! fp needed: %d\n", frame_pointer_needed);
1390 fprintf (file, "\t! pretend_args: %d\n", cfun->machine->va_args_size);
1391 fprintf (file, "\t! local_size: %d\n", cfun->machine->local_size);
1392 fprintf (file, "\t! out_args_size: %d\n", cfun->machine->out_args_size);
1394 /* Use df_regs_ever_live_p() to detect if the register
1395 is ever used in the current function. */
1396 fprintf (file, "\t! registers ever_live: ");
1397 for (r = 0; r < 32; r++)
1399 if (df_regs_ever_live_p (r))
1400 fprintf (file, "%s, ", reg_names[r]);
1402 fputc ('\n', file);
1404 /* Display the attributes of this function. */
1405 fprintf (file, "\t! function attributes: ");
1406 /* Get the attributes tree list.
1407 Note that GCC builds attributes list with reverse order. */
1408 attrs = DECL_ATTRIBUTES (current_function_decl);
1410 /* If there is no any attribute, print out "None". */
1411 if (!attrs)
1412 fprintf (file, "None");
1414 /* If there are some attributes, try if we need to
1415 construct isr vector information. */
1416 func_name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1417 nds32_construct_isr_vectors_information (attrs, func_name);
1419 /* Display all attributes of this function. */
1420 while (attrs)
1422 name = TREE_PURPOSE (attrs);
1423 fprintf (file, "%s ", IDENTIFIER_POINTER (name));
1425 /* Pick up the next attribute. */
1426 attrs = TREE_CHAIN (attrs);
1428 fputc ('\n', file);
1431 /* After rtl prologue has been expanded, this function is used. */
1432 static void
1433 nds32_asm_function_end_prologue (FILE *file)
1435 fprintf (file, "\t! END PROLOGUE\n");
1437 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1438 we can generate special directive: ".omit_fp_begin"
1439 to guide linker doing fp-as-gp optimization.
1440 However, for a naked function, which means
1441 it should not have prologue/epilogue,
1442 using fp-as-gp still requires saving $fp by push/pop behavior and
1443 there is no benefit to use fp-as-gp on such small function.
1444 So we need to make sure this function is NOT naked as well. */
1445 if (!frame_pointer_needed
1446 && !cfun->machine->naked_p
1447 && cfun->machine->fp_as_gp_p)
1449 fprintf (file, "\t! ----------------------------------------\n");
1450 fprintf (file, "\t! Guide linker to do "
1451 "link time optimization: fp-as-gp\n");
1452 fprintf (file, "\t! We add one more instruction to "
1453 "initialize $fp near to $gp location.\n");
1454 fprintf (file, "\t! If linker fails to use fp-as-gp transformation,\n");
1455 fprintf (file, "\t! this extra instruction should be "
1456 "eliminated at link stage.\n");
1457 fprintf (file, "\t.omit_fp_begin\n");
1458 fprintf (file, "\tla\t$fp,_FP_BASE_\n");
1459 fprintf (file, "\t! ----------------------------------------\n");
1463 /* Before rtl epilogue has been expanded, this function is used. */
1464 static void
1465 nds32_asm_function_begin_epilogue (FILE *file)
1467 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
1468 we can generate special directive: ".omit_fp_end"
1469 to claim fp-as-gp optimization range.
1470 However, for a naked function,
1471 which means it should not have prologue/epilogue,
1472 using fp-as-gp still requires saving $fp by push/pop behavior and
1473 there is no benefit to use fp-as-gp on such small function.
1474 So we need to make sure this function is NOT naked as well. */
1475 if (!frame_pointer_needed
1476 && !cfun->machine->naked_p
1477 && cfun->machine->fp_as_gp_p)
1479 fprintf (file, "\t! ----------------------------------------\n");
1480 fprintf (file, "\t! Claim the range of fp-as-gp "
1481 "link time optimization\n");
1482 fprintf (file, "\t.omit_fp_end\n");
1483 fprintf (file, "\t! ----------------------------------------\n");
1486 fprintf (file, "\t! BEGIN EPILOGUE\n");
1489 /* The content produced from this function
1490 will be placed after epilogue body. */
1491 static void
1492 nds32_asm_function_epilogue (FILE *file,
1493 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
1495 fprintf (file, "\t! END EPILOGUE\n");
1498 static void
1499 nds32_asm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
1500 HOST_WIDE_INT delta,
1501 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1502 tree function)
1504 int this_regno;
1506 /* Make sure unwind info is emitted for the thunk if needed. */
1507 final_start_function (emit_barrier (), file, 1);
1509 this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
1511 : 0);
1513 if (delta != 0)
1515 if (satisfies_constraint_Is15 (GEN_INT (delta)))
1517 fprintf (file, "\taddi\t$r%d, $r%d, %ld\n",
1518 this_regno, this_regno, delta);
1520 else if (satisfies_constraint_Is20 (GEN_INT (delta)))
1522 fprintf (file, "\tmovi\t$ta, %ld\n", delta);
1523 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1525 else
1527 fprintf (file, "\tsethi\t$ta, hi20(%ld)\n", delta);
1528 fprintf (file, "\tori\t$ta, $ta, lo12(%ld)\n", delta);
1529 fprintf (file, "\tadd\t$r%d, $r%d, $ta\n", this_regno, this_regno);
1533 fprintf (file, "\tb\t");
1534 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1535 fprintf (file, "\n");
1537 final_end_function ();
1540 /* -- Permitting tail calls. */
1542 /* Determine whether we need to enable warning for function return check. */
1543 static bool
1544 nds32_warn_func_return (tree decl)
1546 /* Naked functions are implemented entirely in assembly, including the
1547 return sequence, so suppress warnings about this. */
1548 return !nds32_naked_function_p (decl);
1552 /* Implementing the Varargs Macros. */
1554 static bool
1555 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED)
1557 /* Return true so that all the named arguments for FUNCTION_ARG have named=1.
1558 If return false, for the variadic function, all named arguments EXCEPT
1559 the last are treated as named. */
1560 return true;
1564 /* Trampolines for Nested Functions. */
1566 static void
1567 nds32_asm_trampoline_template (FILE *f)
1569 if (TARGET_REDUCED_REGS)
1571 /* Trampoline is not supported on reduced-set registers yet. */
1572 sorry ("a nested function is not supported for reduced registers");
1574 else
1576 asm_fprintf (f, "\t! Trampoline code template\n");
1577 asm_fprintf (f, "\t! This code fragment will be copied "
1578 "into stack on demand\n");
1580 asm_fprintf (f, "\tmfusr\t$r16,$pc\n");
1581 asm_fprintf (f, "\tlwi\t$r15,[$r16 + 20] "
1582 "! load nested function address\n");
1583 asm_fprintf (f, "\tlwi\t$r16,[$r16 + 16] "
1584 "! load chain_value\n");
1585 asm_fprintf (f, "\tjr\t$r15\n");
1588 /* Preserve space ($pc + 16) for saving chain_value,
1589 nds32_trampoline_init will fill the value in this slot. */
1590 asm_fprintf (f, "\t! space for saving chain_value\n");
1591 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1593 /* Preserve space ($pc + 20) for saving nested function address,
1594 nds32_trampoline_init will fill the value in this slot. */
1595 asm_fprintf (f, "\t! space for saving nested function address\n");
1596 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
1599 /* Emit RTL insns to initialize the variable parts of a trampoline. */
1600 static void
1601 nds32_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1603 int i;
1605 /* Nested function address. */
1606 rtx fnaddr;
1607 /* The memory rtx that is going to
1608 be filled with chain_value. */
1609 rtx chain_value_mem;
1610 /* The memory rtx that is going to
1611 be filled with nested function address. */
1612 rtx nested_func_mem;
1614 /* Start address of trampoline code in stack, for doing cache sync. */
1615 rtx sync_cache_addr;
1616 /* Temporary register for sync instruction. */
1617 rtx tmp_reg;
1618 /* Instruction-cache sync instruction,
1619 requesting an argument as starting address. */
1620 rtx isync_insn;
1621 /* For convenience reason of doing comparison. */
1622 int tramp_align_in_bytes;
1624 /* Trampoline is not supported on reduced-set registers yet. */
1625 if (TARGET_REDUCED_REGS)
1626 sorry ("a nested function is not supported for reduced registers");
1628 /* STEP 1: Copy trampoline code template into stack,
1629 fill up essential data into stack. */
1631 /* Extract nested function address rtx. */
1632 fnaddr = XEXP (DECL_RTL (fndecl), 0);
1634 /* m_tramp is memory rtx that is going to be filled with trampoline code.
1635 We have nds32_asm_trampoline_template() to emit template pattern. */
1636 emit_block_move (m_tramp, assemble_trampoline_template (),
1637 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
1639 /* After copying trampoline code into stack,
1640 fill chain_value into stack. */
1641 chain_value_mem = adjust_address (m_tramp, SImode, 16);
1642 emit_move_insn (chain_value_mem, chain_value);
1643 /* After copying trampoline code int stack,
1644 fill nested function address into stack. */
1645 nested_func_mem = adjust_address (m_tramp, SImode, 20);
1646 emit_move_insn (nested_func_mem, fnaddr);
1648 /* STEP 2: Sync instruction-cache. */
1650 /* We have successfully filled trampoline code into stack.
1651 However, in order to execute code in stack correctly,
1652 we must sync instruction cache. */
1653 sync_cache_addr = XEXP (m_tramp, 0);
1654 tmp_reg = gen_reg_rtx (SImode);
1655 isync_insn = gen_unspec_volatile_isync (tmp_reg);
1657 /* Because nds32_cache_block_size is in bytes,
1658 we get trampoline alignment in bytes for convenient comparison. */
1659 tramp_align_in_bytes = TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT;
1661 if (tramp_align_in_bytes >= nds32_cache_block_size
1662 && (tramp_align_in_bytes % nds32_cache_block_size) == 0)
1664 /* Under this condition, the starting address of trampoline
1665 must be aligned to the starting address of each cache block
1666 and we do not have to worry about cross-boundary issue. */
1667 for (i = 0;
1668 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1669 / nds32_cache_block_size;
1670 i++)
1672 emit_move_insn (tmp_reg,
1673 plus_constant (Pmode, sync_cache_addr,
1674 nds32_cache_block_size * i));
1675 emit_insn (isync_insn);
1678 else if (TRAMPOLINE_SIZE > nds32_cache_block_size)
1680 /* The starting address of trampoline code
1681 may not be aligned to the cache block,
1682 so the trampoline code may be across two cache block.
1683 We need to sync the last element, which is 4-byte size,
1684 of trampoline template. */
1685 for (i = 0;
1686 i < (TRAMPOLINE_SIZE + nds32_cache_block_size - 1)
1687 / nds32_cache_block_size;
1688 i++)
1690 emit_move_insn (tmp_reg,
1691 plus_constant (Pmode, sync_cache_addr,
1692 nds32_cache_block_size * i));
1693 emit_insn (isync_insn);
1696 /* The last element of trampoline template is 4-byte size. */
1697 emit_move_insn (tmp_reg,
1698 plus_constant (Pmode, sync_cache_addr,
1699 TRAMPOLINE_SIZE - 4));
1700 emit_insn (isync_insn);
1702 else
1704 /* This is the simplest case.
1705 Because TRAMPOLINE_SIZE is less than or
1706 equal to nds32_cache_block_size,
1707 we can just sync start address and
1708 the last element of trampoline code. */
1710 /* Sync starting address of tampoline code. */
1711 emit_move_insn (tmp_reg, sync_cache_addr);
1712 emit_insn (isync_insn);
1713 /* Sync the last element, which is 4-byte size,
1714 of trampoline template. */
1715 emit_move_insn (tmp_reg,
1716 plus_constant (Pmode, sync_cache_addr,
1717 TRAMPOLINE_SIZE - 4));
1718 emit_insn (isync_insn);
1721 /* Set instruction serialization barrier
1722 to guarantee the correct operations. */
1723 emit_insn (gen_unspec_volatile_isb ());
1727 /* Addressing Modes. */
1729 static bool
1730 nds32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1732 /* For (mem:DI addr) or (mem:DF addr) case,
1733 we only allow 'addr' to be [reg], [symbol_ref],
1734 [const], or [reg + const_int] pattern. */
1735 if (mode == DImode || mode == DFmode)
1737 /* Allow [Reg + const_int] addressing mode. */
1738 if (GET_CODE (x) == PLUS)
1740 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1741 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict)
1742 && CONST_INT_P (XEXP (x, 1)))
1743 return true;
1745 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1746 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict)
1747 && CONST_INT_P (XEXP (x, 0)))
1748 return true;
1751 /* Now check [reg], [symbol_ref], and [const]. */
1752 if (GET_CODE (x) != REG
1753 && GET_CODE (x) != SYMBOL_REF
1754 && GET_CODE (x) != CONST)
1755 return false;
1758 /* Check if 'x' is a valid address. */
1759 switch (GET_CODE (x))
1761 case REG:
1762 /* (mem (reg A)) => [Ra] */
1763 return nds32_address_register_rtx_p (x, strict);
1765 case SYMBOL_REF:
1767 if (!TARGET_GP_DIRECT
1768 && (reload_completed
1769 || reload_in_progress
1770 || lra_in_progress))
1771 return false;
1773 /* (mem (symbol_ref A)) => [symbol_ref] */
1774 return !currently_expanding_to_rtl;
1776 case CONST:
1778 if (!TARGET_GP_DIRECT
1779 && (reload_completed
1780 || reload_in_progress
1781 || lra_in_progress))
1782 return false;
1784 /* (mem (const (...)))
1785 => [ + const_addr ], where const_addr = symbol_ref + const_int */
1786 if (GET_CODE (XEXP (x, 0)) == PLUS)
1788 rtx plus_op = XEXP (x, 0);
1790 rtx op0 = XEXP (plus_op, 0);
1791 rtx op1 = XEXP (plus_op, 1);
1793 if (GET_CODE (op0) == SYMBOL_REF && CONST_INT_P (op1))
1794 return true;
1795 else
1796 return false;
1799 return false;
1801 case POST_MODIFY:
1802 /* (mem (post_modify (reg) (plus (reg) (reg))))
1803 => [Ra], Rb */
1804 /* (mem (post_modify (reg) (plus (reg) (const_int))))
1805 => [Ra], const_int */
1806 if (GET_CODE (XEXP (x, 0)) == REG
1807 && GET_CODE (XEXP (x, 1)) == PLUS)
1809 rtx plus_op = XEXP (x, 1);
1811 rtx op0 = XEXP (plus_op, 0);
1812 rtx op1 = XEXP (plus_op, 1);
1814 if (nds32_address_register_rtx_p (op0, strict)
1815 && nds32_legitimate_index_p (mode, op1, strict))
1816 return true;
1817 else
1818 return false;
1821 return false;
1823 case POST_INC:
1824 case POST_DEC:
1825 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
1826 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
1827 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
1828 We only need to deal with register Ra. */
1829 if (nds32_address_register_rtx_p (XEXP (x, 0), strict))
1830 return true;
1831 else
1832 return false;
1834 case PLUS:
1835 /* (mem (plus reg const_int))
1836 => [Ra + imm] */
1837 /* (mem (plus reg reg))
1838 => [Ra + Rb] */
1839 /* (mem (plus (mult reg const_int) reg))
1840 => [Ra + Rb << sv] */
1841 if (nds32_address_register_rtx_p (XEXP (x, 0), strict)
1842 && nds32_legitimate_index_p (mode, XEXP (x, 1), strict))
1843 return true;
1844 else if (nds32_address_register_rtx_p (XEXP (x, 1), strict)
1845 && nds32_legitimate_index_p (mode, XEXP (x, 0), strict))
1846 return true;
1847 else
1848 return false;
1850 case LO_SUM:
1851 if (!TARGET_GP_DIRECT)
1852 return true;
1854 default:
1855 return false;
1860 /* Describing Relative Costs of Operations. */
1862 static int
1863 nds32_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1864 reg_class_t from,
1865 reg_class_t to)
1867 if (from == HIGH_REGS || to == HIGH_REGS)
1868 return 6;
1870 return 2;
1873 static int
1874 nds32_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
1875 reg_class_t rclass ATTRIBUTE_UNUSED,
1876 bool in ATTRIBUTE_UNUSED)
1878 return 8;
1881 /* This target hook describes the relative costs of RTL expressions.
1882 Return 'true' when all subexpressions of x have been processed.
1883 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
1884 Refer to gcc/rtlanal.c for more information. */
1885 static bool
1886 nds32_rtx_costs (rtx x,
1887 int code,
1888 int outer_code,
1889 int opno,
1890 int *total,
1891 bool speed)
1893 return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
1896 static int
1897 nds32_address_cost (rtx address,
1898 enum machine_mode mode,
1899 addr_space_t as,
1900 bool speed)
1902 return nds32_address_cost_impl (address, mode, as, speed);
1906 /* Defining the Output Assembler Language. */
1908 /* -- The Overall Framework of an Assembler File. */
1910 static void
1911 nds32_asm_file_start (void)
1913 default_file_start ();
1915 /* Tell assembler which ABI we are using. */
1916 fprintf (asm_out_file, "\t! ABI version\n");
1917 fprintf (asm_out_file, "\t.abi_2\n");
1919 /* Tell assembler that this asm code is generated by compiler. */
1920 fprintf (asm_out_file, "\t! This asm file is generated by compiler\n");
1921 fprintf (asm_out_file, "\t.flag\tverbatim\n");
1922 /* Give assembler the size of each vector for interrupt handler. */
1923 fprintf (asm_out_file, "\t! This vector size directive is required "
1924 "for checking inconsistency on interrupt handler\n");
1925 fprintf (asm_out_file, "\t.vec_size\t%d\n", nds32_isr_vector_size);
1927 /* If user enables '-mforce-fp-as-gp' or compiles programs with -Os,
1928 the compiler may produce 'la $fp,_FP_BASE_' instruction
1929 at prologue for fp-as-gp optimization.
1930 We should emit weak reference of _FP_BASE_ to avoid undefined reference
1931 in case user does not pass '--relax' option to linker. */
1932 if (TARGET_FORCE_FP_AS_GP || optimize_size)
1934 fprintf (asm_out_file, "\t! This weak reference is required to do "
1935 "fp-as-gp link time optimization\n");
1936 fprintf (asm_out_file, "\t.weak\t_FP_BASE_\n");
1938 /* If user enables '-mex9', we should emit relaxation directive
1939 to tell linker that this file is allowed to do ex9 optimization. */
1940 if (TARGET_EX9)
1942 fprintf (asm_out_file, "\t! This relaxation directive is required "
1943 "to do ex9 link time optimization\n");
1944 fprintf (asm_out_file, "\t.relax\tex9\n");
1947 fprintf (asm_out_file, "\t! ------------------------------------\n");
1949 if (TARGET_ISA_V2)
1950 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V2");
1951 if (TARGET_ISA_V3)
1952 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3");
1953 if (TARGET_ISA_V3M)
1954 fprintf (asm_out_file, "\t! ISA family\t\t: %s\n", "V3M");
1956 fprintf (asm_out_file, "\t! Endian setting\t: %s\n",
1957 ((TARGET_BIG_ENDIAN) ? "big-endian"
1958 : "little-endian"));
1960 fprintf (asm_out_file, "\t! ------------------------------------\n");
1962 fprintf (asm_out_file, "\t! Use conditional move\t\t: %s\n",
1963 ((TARGET_CMOV) ? "Yes"
1964 : "No"));
1965 fprintf (asm_out_file, "\t! Use performance extension\t: %s\n",
1966 ((TARGET_PERF_EXT) ? "Yes"
1967 : "No"));
1969 fprintf (asm_out_file, "\t! ------------------------------------\n");
1971 fprintf (asm_out_file, "\t! V3PUSH instructions\t: %s\n",
1972 ((TARGET_V3PUSH) ? "Yes"
1973 : "No"));
1974 fprintf (asm_out_file, "\t! 16-bit instructions\t: %s\n",
1975 ((TARGET_16_BIT) ? "Yes"
1976 : "No"));
1977 fprintf (asm_out_file, "\t! GP base access\t: %s\n",
1978 ((TARGET_GP_DIRECT) ? "Yes"
1979 : "No"));
1980 fprintf (asm_out_file, "\t! Reduced registers set\t: %s\n",
1981 ((TARGET_REDUCED_REGS) ? "Yes"
1982 : "No"));
1984 fprintf (asm_out_file, "\t! ------------------------------------\n");
1986 if (optimize_size)
1987 fprintf (asm_out_file, "\t! Optimization level\t: -Os\n");
1988 else
1989 fprintf (asm_out_file, "\t! Optimization level\t: -O%d\n", optimize);
1991 fprintf (asm_out_file, "\t! ------------------------------------\n");
1993 fprintf (asm_out_file, "\t! Cache block size\t: %d\n",
1994 nds32_cache_block_size);
1996 fprintf (asm_out_file, "\t! ------------------------------------\n");
1998 nds32_asm_file_start_for_isr ();
2001 static void
2002 nds32_asm_file_end (void)
2004 nds32_asm_file_end_for_isr ();
2006 fprintf (asm_out_file, "\t! ------------------------------------\n");
2009 /* -- Output and Generation of Labels. */
2011 static void
2012 nds32_asm_globalize_label (FILE *stream, const char *name)
2014 fputs ("\t.global\t", stream);
2015 assemble_name (stream, name);
2016 fputs ("\n", stream);
2019 /* -- Output of Assembler Instructions. */
2021 static void
2022 nds32_print_operand (FILE *stream, rtx x, int code)
2024 int op_value;
2026 switch (code)
2028 case 0 :
2029 /* Do nothing special. */
2030 break;
2032 case 'V':
2033 /* 'x' is supposed to be CONST_INT, get the value. */
2034 gcc_assert (CONST_INT_P (x));
2035 op_value = INTVAL (x);
2037 /* According to the Andes architecture,
2038 the system/user register index range is 0 ~ 1023.
2039 In order to avoid conflict between user-specified-integer value
2040 and enum-specified-register value,
2041 the 'enum nds32_intrinsic_registers' value
2042 in nds32_intrinsic.h starts from 1024. */
2043 if (op_value < 1024 && op_value >= 0)
2045 /* If user gives integer value directly (0~1023),
2046 we just print out the value. */
2047 fprintf (stream, "%d", op_value);
2049 else if (op_value < 0
2050 || op_value >= ((int) ARRAY_SIZE (nds32_intrinsic_register_names)
2051 + 1024))
2053 /* The enum index value for array size is out of range. */
2054 error ("intrinsic register index is out of range");
2056 else
2058 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
2059 we can print out register name. Remember to substract 1024. */
2060 fprintf (stream, "%s",
2061 nds32_intrinsic_register_names[op_value - 1024]);
2064 /* No need to handle following process, so return immediately. */
2065 return;
2067 default :
2068 /* Unknown flag. */
2069 output_operand_lossage ("invalid operand output code");
2070 break;
2073 switch (GET_CODE (x))
2075 case LABEL_REF:
2076 case SYMBOL_REF:
2077 output_addr_const (stream, x);
2078 break;
2080 case REG:
2081 /* Forbid using static chain register ($r16)
2082 on reduced-set registers configuration. */
2083 if (TARGET_REDUCED_REGS
2084 && REGNO (x) == STATIC_CHAIN_REGNUM)
2085 sorry ("a nested function is not supported for reduced registers");
2087 /* Normal cases, print out register name. */
2088 fputs (reg_names[REGNO (x)], stream);
2089 break;
2091 case MEM:
2092 output_address (XEXP (x, 0));
2093 break;
2095 case CODE_LABEL:
2096 case CONST_INT:
2097 case CONST:
2098 output_addr_const (stream, x);
2099 break;
2101 default:
2102 /* Generally, output_addr_const () is able to handle most cases.
2103 We want to see what CODE could appear,
2104 so we use gcc_unreachable() to stop it. */
2105 debug_rtx (x);
2106 gcc_unreachable ();
2107 break;
2111 static void
2112 nds32_print_operand_address (FILE *stream, rtx x)
2114 rtx op0, op1;
2116 switch (GET_CODE (x))
2118 case SYMBOL_REF:
2119 case CONST:
2120 /* [ + symbol_ref] */
2121 /* [ + const_addr], where const_addr = symbol_ref + const_int */
2122 fputs ("[ + ", stream);
2123 output_addr_const (stream, x);
2124 fputs ("]", stream);
2125 break;
2127 case REG:
2128 /* Forbid using static chain register ($r16)
2129 on reduced-set registers configuration. */
2130 if (TARGET_REDUCED_REGS
2131 && REGNO (x) == STATIC_CHAIN_REGNUM)
2132 sorry ("a nested function is not supported for reduced registers");
2134 /* [Ra] */
2135 fprintf (stream, "[%s]", reg_names[REGNO (x)]);
2136 break;
2138 case PLUS:
2139 op0 = XEXP (x, 0);
2140 op1 = XEXP (x, 1);
2142 /* Checking op0, forbid using static chain register ($r16)
2143 on reduced-set registers configuration. */
2144 if (TARGET_REDUCED_REGS
2145 && REG_P (op0)
2146 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2147 sorry ("a nested function is not supported for reduced registers");
2148 /* Checking op1, forbid using static chain register ($r16)
2149 on reduced-set registers configuration. */
2150 if (TARGET_REDUCED_REGS
2151 && REG_P (op1)
2152 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2153 sorry ("a nested function is not supported for reduced registers");
2155 if (REG_P (op0) && CONST_INT_P (op1))
2157 /* [Ra + imm] */
2158 fprintf (stream, "[%s + (%d)]",
2159 reg_names[REGNO (op0)], (int)INTVAL (op1));
2161 else if (REG_P (op0) && REG_P (op1))
2163 /* [Ra + Rb] */
2164 fprintf (stream, "[%s + %s]",
2165 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2167 else if (GET_CODE (op0) == MULT && REG_P (op1))
2169 /* [Ra + Rb << sv]
2170 From observation, the pattern looks like:
2171 (plus:SI (mult:SI (reg:SI 58)
2172 (const_int 4 [0x4]))
2173 (reg/f:SI 57)) */
2174 int sv;
2176 /* We need to set sv to output shift value. */
2177 if (INTVAL (XEXP (op0, 1)) == 1)
2178 sv = 0;
2179 else if (INTVAL (XEXP (op0, 1)) == 2)
2180 sv = 1;
2181 else if (INTVAL (XEXP (op0, 1)) == 4)
2182 sv = 2;
2183 else
2184 gcc_unreachable ();
2186 fprintf (stream, "[%s + %s << %d]",
2187 reg_names[REGNO (op1)],
2188 reg_names[REGNO (XEXP (op0, 0))],
2189 sv);
2191 else
2193 /* The control flow is not supposed to be here. */
2194 debug_rtx (x);
2195 gcc_unreachable ();
2198 break;
2200 case POST_MODIFY:
2201 /* (post_modify (regA) (plus (regA) (regB)))
2202 (post_modify (regA) (plus (regA) (const_int)))
2203 We would like to extract
2204 regA and regB (or const_int) from plus rtx. */
2205 op0 = XEXP (XEXP (x, 1), 0);
2206 op1 = XEXP (XEXP (x, 1), 1);
2208 /* Checking op0, forbid using static chain register ($r16)
2209 on reduced-set registers configuration. */
2210 if (TARGET_REDUCED_REGS
2211 && REG_P (op0)
2212 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2213 sorry ("a nested function is not supported for reduced registers");
2214 /* Checking op1, forbid using static chain register ($r16)
2215 on reduced-set registers configuration. */
2216 if (TARGET_REDUCED_REGS
2217 && REG_P (op1)
2218 && REGNO (op1) == STATIC_CHAIN_REGNUM)
2219 sorry ("a nested function is not supported for reduced registers");
2221 if (REG_P (op0) && REG_P (op1))
2223 /* [Ra], Rb */
2224 fprintf (stream, "[%s], %s",
2225 reg_names[REGNO (op0)], reg_names[REGNO (op1)]);
2227 else if (REG_P (op0) && CONST_INT_P (op1))
2229 /* [Ra], imm */
2230 fprintf (stream, "[%s], %d",
2231 reg_names[REGNO (op0)], (int)INTVAL (op1));
2233 else
2235 /* The control flow is not supposed to be here. */
2236 debug_rtx (x);
2237 gcc_unreachable ();
2240 break;
2242 case POST_INC:
2243 case POST_DEC:
2244 op0 = XEXP (x, 0);
2246 /* Checking op0, forbid using static chain register ($r16)
2247 on reduced-set registers configuration. */
2248 if (TARGET_REDUCED_REGS
2249 && REG_P (op0)
2250 && REGNO (op0) == STATIC_CHAIN_REGNUM)
2251 sorry ("a nested function is not supported for reduced registers");
2253 if (REG_P (op0))
2255 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
2256 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2257 We only need to deal with register Ra. */
2258 fprintf (stream, "[%s]", reg_names[REGNO (op0)]);
2260 else
2262 /* The control flow is not supposed to be here. */
2263 debug_rtx (x);
2264 gcc_unreachable ();
2267 break;
2269 default :
2270 /* Generally, output_addr_const () is able to handle most cases.
2271 We want to see what CODE could appear,
2272 so we use gcc_unreachable() to stop it. */
2273 debug_rtx (x);
2274 gcc_unreachable ();
2275 break;
2280 /* Defining target-specific uses of __attribute__. */
2282 /* Add some checking after merging attributes. */
2283 static tree
2284 nds32_merge_decl_attributes (tree olddecl, tree newdecl)
2286 tree combined_attrs;
2288 /* Create combined attributes. */
2289 combined_attrs = merge_attributes (DECL_ATTRIBUTES (olddecl),
2290 DECL_ATTRIBUTES (newdecl));
2292 /* Since newdecl is acutally a duplicate of olddecl,
2293 we can take olddecl for some operations. */
2294 if (TREE_CODE (olddecl) == FUNCTION_DECL)
2296 /* Check isr-specific attributes conflict. */
2297 nds32_check_isr_attrs_conflict (olddecl, combined_attrs);
2300 return combined_attrs;
2303 /* Add some checking when inserting attributes. */
2304 static void
2305 nds32_insert_attributes (tree decl, tree *attributes)
2307 /* For function declaration, we need to check isr-specific attributes:
2308 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
2309 2. Check valid integer value for interrupt/exception.
2310 3. Check valid integer value for reset.
2311 4. Check valid function for nmi/warm. */
2312 if (TREE_CODE (decl) == FUNCTION_DECL)
2314 tree func_attrs;
2315 tree intr, excp, reset;
2317 /* Pick up function attributes. */
2318 func_attrs = *attributes;
2320 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
2321 nds32_check_isr_attrs_conflict (decl, func_attrs);
2323 /* Now we are starting to check valid id value
2324 for interrupt/exception/reset.
2325 Note that we ONLY check its validity here.
2326 To construct isr vector information, it is still performed
2327 by nds32_construct_isr_vectors_information(). */
2328 intr = lookup_attribute ("interrupt", func_attrs);
2329 excp = lookup_attribute ("exception", func_attrs);
2330 reset = lookup_attribute ("reset", func_attrs);
2332 if (intr || excp)
2334 /* Deal with interrupt/exception. */
2335 tree id_list;
2336 unsigned int lower_bound, upper_bound;
2338 /* The way to handle interrupt or exception is the same,
2339 we just need to take care of actual vector number.
2340 For interrupt(0..63), the actual vector number is (9..72).
2341 For exception(1..8), the actual vector number is (1..8). */
2342 lower_bound = (intr) ? (0) : (1);
2343 upper_bound = (intr) ? (63) : (8);
2345 /* Prepare id list so that we can traverse id value. */
2346 id_list = (intr) ? (TREE_VALUE (intr)) : (TREE_VALUE (excp));
2348 /* 2. Check valid integer value for interrupt/exception. */
2349 while (id_list)
2351 tree id;
2353 /* Pick up each vector id value. */
2354 id = TREE_VALUE (id_list);
2355 /* Issue error if it is not a valid integer value. */
2356 if (TREE_CODE (id) != INTEGER_CST
2357 || wi::ltu_p (id, lower_bound)
2358 || wi::gtu_p (id, upper_bound))
2359 error ("invalid id value for interrupt/exception attribute");
2361 /* Advance to next id. */
2362 id_list = TREE_CHAIN (id_list);
2365 else if (reset)
2367 /* Deal with reset. */
2368 tree id_list;
2369 tree id;
2370 tree nmi, warm;
2371 unsigned int lower_bound;
2372 unsigned int upper_bound;
2374 /* Prepare id_list and identify id value so that
2375 we can check if total number of vectors is valid. */
2376 id_list = TREE_VALUE (reset);
2377 id = TREE_VALUE (id_list);
2379 /* The maximum numbers for user's interrupt is 64. */
2380 lower_bound = 0;
2381 upper_bound = 64;
2383 /* 3. Check valid integer value for reset. */
2384 if (TREE_CODE (id) != INTEGER_CST
2385 || wi::ltu_p (id, lower_bound)
2386 || wi::gtu_p (id, upper_bound))
2387 error ("invalid id value for reset attribute");
2389 /* 4. Check valid function for nmi/warm. */
2390 nmi = lookup_attribute ("nmi", func_attrs);
2391 warm = lookup_attribute ("warm", func_attrs);
2393 if (nmi != NULL_TREE)
2395 tree nmi_func_list;
2396 tree nmi_func;
2398 nmi_func_list = TREE_VALUE (nmi);
2399 nmi_func = TREE_VALUE (nmi_func_list);
2401 /* Issue error if it is not a valid nmi function. */
2402 if (TREE_CODE (nmi_func) != IDENTIFIER_NODE)
2403 error ("invalid nmi function for reset attribute");
2406 if (warm != NULL_TREE)
2408 tree warm_func_list;
2409 tree warm_func;
2411 warm_func_list = TREE_VALUE (warm);
2412 warm_func = TREE_VALUE (warm_func_list);
2414 /* Issue error if it is not a valid warm function. */
2415 if (TREE_CODE (warm_func) != IDENTIFIER_NODE)
2416 error ("invalid warm function for reset attribute");
2419 else
2421 /* No interrupt, exception, or reset attribute is set. */
2422 return;
2427 static bool
2428 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED,
2429 tree pop_target ATTRIBUTE_UNUSED)
2431 /* Currently, we do not parse any pragma target by ourself,
2432 so just simply return false. */
2433 return false;
2436 static void
2437 nds32_option_override (void)
2439 /* After all the command options have been parsed,
2440 we shall deal with some flags for changing compiler settings. */
2442 /* At first, we check if we have to strictly
2443 set some flags based on ISA family. */
2444 if (TARGET_ISA_V2)
2446 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
2447 target_flags &= ~MASK_V3PUSH;
2449 if (TARGET_ISA_V3)
2451 /* Under V3 ISA, currently nothing should be strictly set. */
2453 if (TARGET_ISA_V3M)
2455 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
2456 target_flags |= MASK_REDUCED_REGS;
2457 /* Under V3M ISA, we need to strictly disable TARGET_PERF_EXT. */
2458 target_flags &= ~MASK_PERF_EXT;
2461 /* See if we are using reduced-set registers:
2462 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
2463 If so, we must forbid using $r11~$r14, $r16~$r27. */
2464 if (TARGET_REDUCED_REGS)
2466 int r;
2468 /* Prevent register allocator from
2469 choosing it as doing register allocation. */
2470 for (r = 11; r <= 14; r++)
2471 fixed_regs[r] = call_used_regs[r] = 1;
2472 for (r = 16; r <= 27; r++)
2473 fixed_regs[r] = call_used_regs[r] = 1;
2476 /* See if user explicitly would like to use fp-as-gp optimization.
2477 If so, we must prevent $fp from being allocated
2478 during register allocation. */
2479 if (TARGET_FORCE_FP_AS_GP)
2480 fixed_regs[FP_REGNUM] = call_used_regs[FP_REGNUM] = 1;
2482 if (!TARGET_16_BIT)
2484 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
2485 target_flags &= ~MASK_V3PUSH;
2488 /* Currently, we don't support PIC code generation yet. */
2489 if (flag_pic)
2490 sorry ("not support -fpic");
2494 /* Miscellaneous Parameters. */
2496 static void
2497 nds32_init_builtins (void)
2499 nds32_init_builtins_impl ();
2502 static rtx
2503 nds32_expand_builtin (tree exp,
2504 rtx target,
2505 rtx subtarget,
2506 enum machine_mode mode,
2507 int ignore)
2509 return nds32_expand_builtin_impl (exp, target, subtarget, mode, ignore);
2513 /* ------------------------------------------------------------------------ */
2515 /* PART 4: Implemet extern function definitions,
2516 the prototype is in nds32-protos.h. */
2518 /* Defining Data Structures for Per-function Information. */
2520 void
2521 nds32_init_expanders (void)
2523 /* Arrange to initialize and mark the machine per-function status. */
2524 init_machine_status = nds32_init_machine_status;
2528 /* Register Usage. */
2530 /* -- How Values Fit in Registers. */
2533 nds32_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
2534 enum machine_mode mode)
2536 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
2540 nds32_hard_regno_mode_ok (int regno, enum machine_mode mode)
2542 /* Restrict double-word quantities to even register pairs. */
2543 if (HARD_REGNO_NREGS (regno, mode) == 1
2544 || !((regno) & 1))
2545 return 1;
2547 return 0;
2551 /* Register Classes. */
2553 enum reg_class
2554 nds32_regno_reg_class (int regno)
2556 /* Refer to nds32.h for more register class details. */
2558 if (regno >= 0 && regno <= 7)
2559 return LOW_REGS;
2560 else if (regno >= 8 && regno <= 11)
2561 return MIDDLE_REGS;
2562 else if (regno >= 12 && regno <= 14)
2563 return HIGH_REGS;
2564 else if (regno == 15)
2565 return R15_TA_REG;
2566 else if (regno >= 16 && regno <= 19)
2567 return MIDDLE_REGS;
2568 else if (regno >= 20 && regno <= 31)
2569 return HIGH_REGS;
2570 else if (regno == 32 || regno == 33)
2571 return FRAME_REGS;
2572 else
2573 return NO_REGS;
2577 /* Stack Layout and Calling Conventions. */
2579 /* -- Basic Stack Layout. */
2582 nds32_return_addr_rtx (int count,
2583 rtx frameaddr ATTRIBUTE_UNUSED)
2585 /* There is no way to determine the return address
2586 if frameaddr is the frame that has 'count' steps
2587 up from current frame. */
2588 if (count != 0)
2589 return NULL_RTX;
2591 /* If count == 0, it means we are at current frame,
2592 the return address is $r30 ($lp). */
2593 return get_hard_reg_initial_val (Pmode, LP_REGNUM);
2596 /* -- Eliminating Frame Pointer and Arg Pointer. */
2598 HOST_WIDE_INT
2599 nds32_initial_elimination_offset (unsigned int from_reg, unsigned int to_reg)
2601 HOST_WIDE_INT offset;
2603 /* Compute and setup stack frame size.
2604 The result will be in cfun->machine. */
2605 nds32_compute_stack_frame ();
2607 /* Remember to consider
2608 cfun->machine->callee_saved_area_padding_bytes
2609 when calculating offset. */
2610 if (from_reg == ARG_POINTER_REGNUM && to_reg == STACK_POINTER_REGNUM)
2612 offset = (cfun->machine->fp_size
2613 + cfun->machine->gp_size
2614 + cfun->machine->lp_size
2615 + cfun->machine->callee_saved_regs_size
2616 + cfun->machine->callee_saved_area_padding_bytes
2617 + cfun->machine->local_size
2618 + cfun->machine->out_args_size);
2620 else if (from_reg == ARG_POINTER_REGNUM
2621 && to_reg == HARD_FRAME_POINTER_REGNUM)
2623 offset = 0;
2625 else if (from_reg == FRAME_POINTER_REGNUM
2626 && to_reg == STACK_POINTER_REGNUM)
2628 offset = (cfun->machine->local_size + cfun->machine->out_args_size);
2630 else if (from_reg == FRAME_POINTER_REGNUM
2631 && to_reg == HARD_FRAME_POINTER_REGNUM)
2633 offset = (-1) * (cfun->machine->fp_size
2634 + cfun->machine->gp_size
2635 + cfun->machine->lp_size
2636 + cfun->machine->callee_saved_regs_size
2637 + cfun->machine->callee_saved_area_padding_bytes);
2639 else
2641 gcc_unreachable ();
2644 return offset;
2647 /* -- Passing Arguments in Registers. */
2649 void
2650 nds32_init_cumulative_args (CUMULATIVE_ARGS *cum,
2651 tree fntype ATTRIBUTE_UNUSED,
2652 rtx libname ATTRIBUTE_UNUSED,
2653 tree fndecl ATTRIBUTE_UNUSED,
2654 int n_named_args ATTRIBUTE_UNUSED)
2656 /* Initial available registers
2657 (in offset, corresponding to NDS32_GPR_ARG_FIRST_REGNUM)
2658 for passing arguments. */
2659 cum->reg_offset = 0;
2662 /* -- Function Entry and Exit. */
2664 /* Function for normal multiple push prologue. */
2665 void
2666 nds32_expand_prologue (void)
2668 int fp_adjust;
2669 int sp_adjust;
2670 int en4_const;
2672 rtx Rb, Re;
2673 rtx fp_adjust_insn, sp_adjust_insn;
2675 /* Before computing everything for stack frame size,
2676 we check if it is still worth to use fp_as_gp optimization.
2677 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2678 so that $fp will be saved on stack. */
2679 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
2681 /* Compute and setup stack frame size.
2682 The result will be in cfun->machine. */
2683 nds32_compute_stack_frame ();
2685 /* If the function is 'naked',
2686 we do not have to generate prologue code fragment. */
2687 if (cfun->machine->naked_p)
2688 return;
2690 /* Get callee_first_regno and callee_last_regno. */
2691 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2692 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2694 /* nds32_emit_stack_push_multiple(first_regno, last_regno),
2695 the pattern 'stack_push_multiple' is implemented in nds32.md.
2696 For En4 field, we have to calculate its constant value.
2697 Refer to Andes ISA for more information. */
2698 en4_const = 0;
2699 if (cfun->machine->fp_size)
2700 en4_const += 8;
2701 if (cfun->machine->gp_size)
2702 en4_const += 4;
2703 if (cfun->machine->lp_size)
2704 en4_const += 2;
2706 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2707 to be saved, we don't have to create multiple push instruction.
2708 Otherwise, a multiple push instruction is needed. */
2709 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2711 /* Create multiple push instruction rtx. */
2712 nds32_emit_stack_push_multiple (Rb, Re, GEN_INT (en4_const));
2715 /* Check frame_pointer_needed to see
2716 if we shall emit fp adjustment instruction. */
2717 if (frame_pointer_needed)
2719 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
2720 + (4 * callee-saved-registers)
2721 Note: No need to adjust
2722 cfun->machine->callee_saved_area_padding_bytes,
2723 because, at this point, stack pointer is just
2724 at the position after push instruction. */
2725 fp_adjust = cfun->machine->fp_size
2726 + cfun->machine->gp_size
2727 + cfun->machine->lp_size
2728 + cfun->machine->callee_saved_regs_size;
2729 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2730 stack_pointer_rtx,
2731 GEN_INT (fp_adjust));
2732 /* Emit rtx into instructions list and receive INSN rtx form. */
2733 fp_adjust_insn = emit_insn (fp_adjust_insn);
2736 /* Adjust $sp = $sp - local_size - out_args_size
2737 - callee_saved_area_padding_bytes. */
2738 sp_adjust = cfun->machine->local_size
2739 + cfun->machine->out_args_size
2740 + cfun->machine->callee_saved_area_padding_bytes;
2741 /* sp_adjust value may be out of range of the addi instruction,
2742 create alternative add behavior with TA_REGNUM if necessary,
2743 using NEGATIVE value to tell that we are decreasing address. */
2744 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2745 if (sp_adjust)
2747 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
2748 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2749 stack_pointer_rtx,
2750 GEN_INT (-1 * sp_adjust));
2751 /* Emit rtx into instructions list and receive INSN rtx form. */
2752 sp_adjust_insn = emit_insn (sp_adjust_insn);
2754 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2755 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2756 generate CFI (Call Frame Information) stuff. */
2757 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
2760 /* Prevent the instruction scheduler from
2761 moving instructions across the boundary. */
2762 emit_insn (gen_blockage ());
2765 /* Function for normal multiple pop epilogue. */
2766 void
2767 nds32_expand_epilogue (void)
2769 int sp_adjust;
2770 int en4_const;
2772 rtx Rb, Re;
2773 rtx sp_adjust_insn;
2775 /* Compute and setup stack frame size.
2776 The result will be in cfun->machine. */
2777 nds32_compute_stack_frame ();
2779 /* Prevent the instruction scheduler from
2780 moving instructions across the boundary. */
2781 emit_insn (gen_blockage ());
2783 /* If the function is 'naked', we do not have to generate
2784 epilogue code fragment BUT 'ret' instruction. */
2785 if (cfun->machine->naked_p)
2787 /* Generate return instruction by using
2788 unspec_volatile_func_return pattern.
2789 Make sure this instruction is after gen_blockage().
2790 NOTE that $lp will become 'live'
2791 after this instruction has been emitted. */
2792 emit_insn (gen_unspec_volatile_func_return ());
2793 return;
2796 if (frame_pointer_needed)
2798 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
2799 - (4 * callee-saved-registers)
2800 Note: No need to adjust
2801 cfun->machine->callee_saved_area_padding_bytes,
2802 because we want to adjust stack pointer
2803 to the position for pop instruction. */
2804 sp_adjust = cfun->machine->fp_size
2805 + cfun->machine->gp_size
2806 + cfun->machine->lp_size
2807 + cfun->machine->callee_saved_regs_size;
2808 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2809 hard_frame_pointer_rtx,
2810 GEN_INT (-1 * sp_adjust));
2811 /* Emit rtx into instructions list and receive INSN rtx form. */
2812 sp_adjust_insn = emit_insn (sp_adjust_insn);
2814 else
2816 /* If frame pointer is NOT needed,
2817 we cannot calculate the sp adjustment from frame pointer.
2818 Instead, we calculate the adjustment by local_size,
2819 out_args_size, and callee_saved_area_padding_bytes.
2820 Notice that such sp adjustment value may be out of range,
2821 so we have to deal with it as well. */
2823 /* Adjust $sp = $sp + local_size + out_args_size
2824 + callee_saved_area_padding_bytes. */
2825 sp_adjust = cfun->machine->local_size
2826 + cfun->machine->out_args_size
2827 + cfun->machine->callee_saved_area_padding_bytes;
2828 /* sp_adjust value may be out of range of the addi instruction,
2829 create alternative add behavior with TA_REGNUM if necessary,
2830 using POSITIVE value to tell that we are increasing address. */
2831 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
2832 if (sp_adjust)
2834 /* Generate sp adjustment instruction
2835 if and only if sp_adjust != 0. */
2836 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2837 stack_pointer_rtx,
2838 GEN_INT (sp_adjust));
2839 /* Emit rtx into instructions list and receive INSN rtx form. */
2840 sp_adjust_insn = emit_insn (sp_adjust_insn);
2844 /* Get callee_first_regno and callee_last_regno. */
2845 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2846 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2848 /* nds32_emit_stack_pop_multiple(first_regno, last_regno),
2849 the pattern 'stack_pop_multiple' is implementad in nds32.md.
2850 For En4 field, we have to calculate its constant value.
2851 Refer to Andes ISA for more information. */
2852 en4_const = 0;
2853 if (cfun->machine->fp_size)
2854 en4_const += 8;
2855 if (cfun->machine->gp_size)
2856 en4_const += 4;
2857 if (cfun->machine->lp_size)
2858 en4_const += 2;
2860 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
2861 to be saved, we don't have to create multiple pop instruction.
2862 Otherwise, a multiple pop instruction is needed. */
2863 if (!(REGNO (Rb) == SP_REGNUM && REGNO (Re) == SP_REGNUM && en4_const == 0))
2865 /* Create multiple pop instruction rtx. */
2866 nds32_emit_stack_pop_multiple (Rb, Re, GEN_INT (en4_const));
2869 /* Generate return instruction by using
2870 unspec_volatile_func_return pattern. */
2871 emit_insn (gen_unspec_volatile_func_return ());
2874 /* Function for v3push prologue. */
2875 void
2876 nds32_expand_prologue_v3push (void)
2878 int fp_adjust;
2879 int sp_adjust;
2881 rtx Rb, Re;
2882 rtx fp_adjust_insn, sp_adjust_insn;
2884 /* Before computing everything for stack frame size,
2885 we check if it is still worth to use fp_as_gp optimization.
2886 If it is, the 'df_regs_ever_live_p (FP_REGNUM)' will be set
2887 so that $fp will be saved on stack. */
2888 cfun->machine->fp_as_gp_p = nds32_fp_as_gp_check_available ();
2890 /* Compute and setup stack frame size.
2891 The result will be in cfun->machine. */
2892 nds32_compute_stack_frame ();
2894 /* If the function is 'naked',
2895 we do not have to generate prologue code fragment. */
2896 if (cfun->machine->naked_p)
2897 return;
2899 /* Get callee_first_regno and callee_last_regno. */
2900 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
2901 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
2903 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
2904 where imm8u has to be 8-byte alignment. */
2905 sp_adjust = cfun->machine->local_size
2906 + cfun->machine->out_args_size
2907 + cfun->machine->callee_saved_area_padding_bytes;
2909 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
2910 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust))
2912 /* We can use 'push25 Re,imm8u'. */
2914 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
2915 the pattern 'stack_v3push' is implemented in nds32.md.
2916 The (const_int 14) means v3push always push { $fp $gp $lp }. */
2917 nds32_emit_stack_v3push (Rb, Re,
2918 GEN_INT (14), GEN_INT (sp_adjust));
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 + sp_adjust ('push25 Re,imm8u')
2929 Note: Since we use 'push25 Re,imm8u',
2930 the position of stack pointer is further
2931 changed after push instruction.
2932 Hence, we need to take sp_adjust value
2933 into consideration. */
2934 fp_adjust = cfun->machine->fp_size
2935 + cfun->machine->gp_size
2936 + cfun->machine->lp_size
2937 + cfun->machine->callee_saved_regs_size
2938 + sp_adjust;
2939 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2940 stack_pointer_rtx,
2941 GEN_INT (fp_adjust));
2942 /* Emit rtx into instructions list and receive INSN rtx form. */
2943 fp_adjust_insn = emit_insn (fp_adjust_insn);
2946 else
2948 /* We have to use 'push25 Re,0' and
2949 expand one more instruction to adjust $sp later. */
2951 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
2952 the pattern 'stack_v3push' is implemented in nds32.md.
2953 The (const_int 14) means v3push always push { $fp $gp $lp }. */
2954 nds32_emit_stack_v3push (Rb, Re,
2955 GEN_INT (14), GEN_INT (0));
2957 /* Check frame_pointer_needed to see
2958 if we shall emit fp adjustment instruction. */
2959 if (frame_pointer_needed)
2961 /* adjust $fp = $sp + 4 ($fp size)
2962 + 4 ($gp size)
2963 + 4 ($lp size)
2964 + (4 * n) (callee-saved registers)
2965 Note: Since we use 'push25 Re,0',
2966 the stack pointer is just at the position
2967 after push instruction.
2968 No need to take sp_adjust into consideration. */
2969 fp_adjust = cfun->machine->fp_size
2970 + cfun->machine->gp_size
2971 + cfun->machine->lp_size
2972 + cfun->machine->callee_saved_regs_size;
2973 fp_adjust_insn = gen_addsi3 (hard_frame_pointer_rtx,
2974 stack_pointer_rtx,
2975 GEN_INT (fp_adjust));
2976 /* Emit rtx into instructions list and receive INSN rtx form. */
2977 fp_adjust_insn = emit_insn (fp_adjust_insn);
2980 /* Because we use 'push25 Re,0',
2981 we need to expand one more instruction to adjust $sp.
2982 However, sp_adjust value may be out of range of the addi instruction,
2983 create alternative add behavior with TA_REGNUM if necessary,
2984 using NEGATIVE value to tell that we are decreasing address. */
2985 sp_adjust = nds32_force_addi_stack_int ( (-1) * sp_adjust);
2986 if (sp_adjust)
2988 /* Generate sp adjustment instruction
2989 if and only if sp_adjust != 0. */
2990 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
2991 stack_pointer_rtx,
2992 GEN_INT (-1 * sp_adjust));
2993 /* Emit rtx into instructions list and receive INSN rtx form. */
2994 sp_adjust_insn = emit_insn (sp_adjust_insn);
2996 /* The insn rtx 'sp_adjust_insn' will change frame layout.
2997 We need to use RTX_FRAME_RELATED_P so that GCC is able to
2998 generate CFI (Call Frame Information) stuff. */
2999 RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
3003 /* Prevent the instruction scheduler from
3004 moving instructions across the boundary. */
3005 emit_insn (gen_blockage ());
3008 /* Function for v3pop epilogue. */
3009 void
3010 nds32_expand_epilogue_v3pop (void)
3012 int sp_adjust;
3014 rtx Rb, Re;
3015 rtx sp_adjust_insn;
3017 /* Compute and setup stack frame size.
3018 The result will be in cfun->machine. */
3019 nds32_compute_stack_frame ();
3021 /* Prevent the instruction scheduler from
3022 moving instructions across the boundary. */
3023 emit_insn (gen_blockage ());
3025 /* If the function is 'naked', we do not have to generate
3026 epilogue code fragment BUT 'ret' instruction. */
3027 if (cfun->machine->naked_p)
3029 /* Generate return instruction by using
3030 unspec_volatile_func_return pattern.
3031 Make sure this instruction is after gen_blockage().
3032 NOTE that $lp will become 'live'
3033 after this instruction has been emitted. */
3034 emit_insn (gen_unspec_volatile_func_return ());
3035 return;
3038 /* Get callee_first_regno and callee_last_regno. */
3039 Rb = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_first_regno);
3040 Re = gen_rtx_REG (SImode, cfun->machine->callee_saved_regs_last_regno);
3042 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
3043 where imm8u has to be 8-byte alignment. */
3044 sp_adjust = cfun->machine->local_size
3045 + cfun->machine->out_args_size
3046 + cfun->machine->callee_saved_area_padding_bytes;
3048 /* We have to consider alloca issue as well.
3049 If the function does call alloca(), the stack pointer is not fixed.
3050 In that case, we cannot use 'pop25 Re,imm8u' directly.
3051 We have to caculate stack pointer from frame pointer
3052 and then use 'pop25 Re,0'.
3053 Of course, the frame_pointer_needed should be nonzero
3054 if the function calls alloca(). */
3055 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust))
3056 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust)
3057 && !cfun->calls_alloca)
3059 /* We can use 'pop25 Re,imm8u'. */
3061 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3062 the pattern 'stack_v3pop' is implementad in nds32.md.
3063 The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3064 nds32_emit_stack_v3pop (Rb, Re,
3065 GEN_INT (14), GEN_INT (sp_adjust));
3067 else
3069 /* We have to use 'pop25 Re,0', and prior to it,
3070 we must expand one more instruction to adjust $sp. */
3072 if (frame_pointer_needed)
3074 /* adjust $sp = $fp - 4 ($fp size)
3075 - 4 ($gp size)
3076 - 4 ($lp size)
3077 - (4 * n) (callee-saved registers)
3078 Note: No need to adjust
3079 cfun->machine->callee_saved_area_padding_bytes,
3080 because we want to adjust stack pointer
3081 to the position for pop instruction. */
3082 sp_adjust = cfun->machine->fp_size
3083 + cfun->machine->gp_size
3084 + cfun->machine->lp_size
3085 + cfun->machine->callee_saved_regs_size;
3086 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3087 hard_frame_pointer_rtx,
3088 GEN_INT (-1 * sp_adjust));
3089 /* Emit rtx into instructions list and receive INSN rtx form. */
3090 sp_adjust_insn = emit_insn (sp_adjust_insn);
3092 else
3094 /* If frame pointer is NOT needed,
3095 we cannot calculate the sp adjustment from frame pointer.
3096 Instead, we calculate the adjustment by local_size,
3097 out_args_size, and callee_saved_area_padding_bytes.
3098 Notice that such sp adjustment value may be out of range,
3099 so we have to deal with it as well. */
3101 /* Adjust $sp = $sp + local_size + out_args_size
3102 + callee_saved_area_padding_bytes. */
3103 sp_adjust = cfun->machine->local_size
3104 + cfun->machine->out_args_size
3105 + cfun->machine->callee_saved_area_padding_bytes;
3106 /* sp_adjust value may be out of range of the addi instruction,
3107 create alternative add behavior with TA_REGNUM if necessary,
3108 using POSITIVE value to tell that we are increasing address. */
3109 sp_adjust = nds32_force_addi_stack_int (sp_adjust);
3110 if (sp_adjust)
3112 /* Generate sp adjustment instruction
3113 if and only if sp_adjust != 0. */
3114 sp_adjust_insn = gen_addsi3 (stack_pointer_rtx,
3115 stack_pointer_rtx,
3116 GEN_INT (sp_adjust));
3117 /* Emit rtx into instructions list and receive INSN rtx form. */
3118 sp_adjust_insn = emit_insn (sp_adjust_insn);
3122 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
3123 the pattern 'stack_v3pop' is implementad in nds32.md. */
3124 /* The (const_int 14) means v3pop always pop { $fp $gp $lp }. */
3125 nds32_emit_stack_v3pop (Rb, Re,
3126 GEN_INT (14), GEN_INT (0));
3130 /* ------------------------------------------------------------------------ */
3132 /* Function to test 333-form for load/store instructions.
3133 This is auxiliary extern function for auxiliary macro in nds32.h.
3134 Because it is a little complicated, we use function instead of macro. */
3135 bool
3136 nds32_ls_333_p (rtx rt, rtx ra, rtx imm, enum machine_mode mode)
3138 if (REGNO_REG_CLASS (REGNO (rt)) == LOW_REGS
3139 && REGNO_REG_CLASS (REGNO (ra)) == LOW_REGS)
3141 if (GET_MODE_SIZE (mode) == 4)
3142 return satisfies_constraint_Iu05 (imm);
3144 if (GET_MODE_SIZE (mode) == 2)
3145 return satisfies_constraint_Iu04 (imm);
3147 if (GET_MODE_SIZE (mode) == 1)
3148 return satisfies_constraint_Iu03 (imm);
3151 return false;
3155 /* Computing the Length of an Insn.
3156 Modifies the length assigned to instruction INSN.
3157 LEN is the initially computed length of the insn. */
3159 nds32_adjust_insn_length (rtx_insn *insn, int length)
3161 rtx src, dst;
3163 switch (recog_memoized (insn))
3165 case CODE_FOR_move_df:
3166 case CODE_FOR_move_di:
3167 /* Adjust length of movd44 to 2. */
3168 src = XEXP (PATTERN (insn), 1);
3169 dst = XEXP (PATTERN (insn), 0);
3171 if (REG_P (src)
3172 && REG_P (dst)
3173 && (REGNO (src) % 2) == 0
3174 && (REGNO (dst) % 2) == 0)
3175 length = 2;
3176 break;
3178 default:
3179 break;
3182 return length;
3186 /* Return align 2 (log base 2) if the next instruction of LABEL is 4 byte. */
3188 nds32_target_alignment (rtx label)
3190 rtx insn;
3192 if (optimize_size)
3193 return 0;
3195 insn = next_active_insn (label);
3197 if (insn == 0)
3198 return 0;
3199 else if ((get_attr_length (insn) % 4) == 0)
3200 return 2;
3201 else
3202 return 0;
3205 /* ------------------------------------------------------------------------ */
3207 /* PART 5: Initialize target hook structure and definitions. */
3209 /* Controlling the Compilation Driver. */
3212 /* Run-time Target Specification. */
3215 /* Defining Data Structures for Per-function Information. */
3218 /* Storage Layout. */
3220 #undef TARGET_PROMOTE_FUNCTION_MODE
3221 #define TARGET_PROMOTE_FUNCTION_MODE \
3222 default_promote_function_mode_always_promote
3225 /* Layout of Source Language Data Types. */
3228 /* Register Usage. */
3230 /* -- Basic Characteristics of Registers. */
3232 /* -- Order of Allocation of Registers. */
3234 /* -- How Values Fit in Registers. */
3236 /* -- Handling Leaf Functions. */
3238 /* -- Registers That Form a Stack. */
3241 /* Register Classes. */
3243 #undef TARGET_CLASS_MAX_NREGS
3244 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
3246 #undef TARGET_LRA_P
3247 #define TARGET_LRA_P hook_bool_void_true
3249 #undef TARGET_REGISTER_PRIORITY
3250 #define TARGET_REGISTER_PRIORITY nds32_register_priority
3253 /* Obsolete Macros for Defining Constraints. */
3256 /* Stack Layout and Calling Conventions. */
3258 /* -- Basic Stack Layout. */
3260 /* -- Exception Handling Support. */
3262 /* -- Specifying How Stack Checking is Done. */
3264 /* -- Registers That Address the Stack Frame. */
3266 /* -- Eliminating Frame Pointer and Arg Pointer. */
3268 #undef TARGET_CAN_ELIMINATE
3269 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
3271 /* -- Passing Function Arguments on the Stack. */
3273 /* -- Passing Arguments in Registers. */
3275 #undef TARGET_FUNCTION_ARG
3276 #define TARGET_FUNCTION_ARG nds32_function_arg
3278 #undef TARGET_FUNCTION_ARG_ADVANCE
3279 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
3281 #undef TARGET_FUNCTION_ARG_BOUNDARY
3282 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
3284 /* -- How Scalar Function Values Are Returned. */
3286 #undef TARGET_FUNCTION_VALUE
3287 #define TARGET_FUNCTION_VALUE nds32_function_value
3289 #undef TARGET_LIBCALL_VALUE
3290 #define TARGET_LIBCALL_VALUE nds32_libcall_value
3292 #undef TARGET_FUNCTION_VALUE_REGNO_P
3293 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
3295 /* -- How Large Values Are Returned. */
3297 /* -- Caller-Saves Register Allocation. */
3299 /* -- Function Entry and Exit. */
3301 #undef TARGET_ASM_FUNCTION_PROLOGUE
3302 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
3304 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
3305 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
3307 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
3308 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
3310 #undef TARGET_ASM_FUNCTION_EPILOGUE
3311 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
3313 #undef TARGET_ASM_OUTPUT_MI_THUNK
3314 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
3316 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3317 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
3319 /* -- Generating Code for Profiling. */
3321 /* -- Permitting tail calls. */
3323 #undef TARGET_WARN_FUNC_RETURN
3324 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
3326 /* Stack smashing protection. */
3329 /* Implementing the Varargs Macros. */
3331 #undef TARGET_STRICT_ARGUMENT_NAMING
3332 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
3335 /* Trampolines for Nested Functions. */
3337 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3338 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
3340 #undef TARGET_TRAMPOLINE_INIT
3341 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
3344 /* Implicit Calls to Library Routines. */
3347 /* Addressing Modes. */
3349 #undef TARGET_LEGITIMATE_ADDRESS_P
3350 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
3353 /* Anchored Addresses. */
3356 /* Condition Code Status. */
3358 /* -- Representation of condition codes using (cc0). */
3360 /* -- Representation of condition codes using registers. */
3362 /* -- Macros to control conditional execution. */
3365 /* Describing Relative Costs of Operations. */
3367 #undef TARGET_REGISTER_MOVE_COST
3368 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
3370 #undef TARGET_MEMORY_MOVE_COST
3371 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
3373 #undef TARGET_RTX_COSTS
3374 #define TARGET_RTX_COSTS nds32_rtx_costs
3376 #undef TARGET_ADDRESS_COST
3377 #define TARGET_ADDRESS_COST nds32_address_cost
3380 /* Adjusting the Instruction Scheduler. */
3383 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3386 /* Position Independent Code. */
3389 /* Defining the Output Assembler Language. */
3391 /* -- The Overall Framework of an Assembler File. */
3393 #undef TARGET_ASM_FILE_START
3394 #define TARGET_ASM_FILE_START nds32_asm_file_start
3395 #undef TARGET_ASM_FILE_END
3396 #define TARGET_ASM_FILE_END nds32_asm_file_end
3398 /* -- Output of Data. */
3400 #undef TARGET_ASM_ALIGNED_HI_OP
3401 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
3403 #undef TARGET_ASM_ALIGNED_SI_OP
3404 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
3406 /* -- Output of Uninitialized Variables. */
3408 /* -- Output and Generation of Labels. */
3410 #undef TARGET_ASM_GLOBALIZE_LABEL
3411 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
3413 /* -- How Initialization Functions Are Handled. */
3415 /* -- Macros Controlling Initialization Routines. */
3417 /* -- Output of Assembler Instructions. */
3419 #undef TARGET_PRINT_OPERAND
3420 #define TARGET_PRINT_OPERAND nds32_print_operand
3421 #undef TARGET_PRINT_OPERAND_ADDRESS
3422 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
3424 /* -- Output of Dispatch Tables. */
3426 /* -- Assembler Commands for Exception Regions. */
3428 /* -- Assembler Commands for Alignment. */
3431 /* Controlling Debugging Information Format. */
3433 /* -- Macros Affecting All Debugging Formats. */
3435 /* -- Specific Options for DBX Output. */
3437 /* -- Open-Ended Hooks for DBX Format. */
3439 /* -- File Names in DBX Format. */
3441 /* -- Macros for SDB and DWARF Output. */
3443 /* -- Macros for VMS Debug Format. */
3446 /* Cross Compilation and Floating Point. */
3449 /* Mode Switching Instructions. */
3452 /* Defining target-specific uses of __attribute__. */
3454 #undef TARGET_ATTRIBUTE_TABLE
3455 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
3457 #undef TARGET_MERGE_DECL_ATTRIBUTES
3458 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
3460 #undef TARGET_INSERT_ATTRIBUTES
3461 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
3463 #undef TARGET_OPTION_PRAGMA_PARSE
3464 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
3466 #undef TARGET_OPTION_OVERRIDE
3467 #define TARGET_OPTION_OVERRIDE nds32_option_override
3470 /* Emulating TLS. */
3473 /* Defining coprocessor specifics for MIPS targets. */
3476 /* Parameters for Precompiled Header Validity Checking. */
3479 /* C++ ABI parameters. */
3482 /* Adding support for named address spaces. */
3485 /* Miscellaneous Parameters. */
3487 #undef TARGET_INIT_BUILTINS
3488 #define TARGET_INIT_BUILTINS nds32_init_builtins
3490 #undef TARGET_EXPAND_BUILTIN
3491 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
3494 /* ------------------------------------------------------------------------ */
3496 /* Initialize the GCC target structure. */
3498 struct gcc_target targetm = TARGET_INITIALIZER;
3500 /* ------------------------------------------------------------------------ */