1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #define IN_TARGET_CODE 1
27 #include "coretypes.h"
32 #include "tree-pass.h"
33 #include "stringpool.h"
38 #include "optabs.h" /* For GEN_FCN. */
42 #include "diagnostic-core.h"
43 #include "stor-layout.h"
49 #include "tm-constrs.h"
54 /* This file should be included last. */
55 #include "target-def.h"
57 /* ------------------------------------------------------------------------ */
59 /* This file is divided into five parts:
61 PART 1: Auxiliary static variable definitions and
62 target hook static variable definitions.
64 PART 2: Auxiliary static function definitions.
66 PART 3: Implement target hook stuff definitions.
68 PART 4: Implemet extern function definitions,
69 the prototype is in nds32-protos.h.
71 PART 5: Initialize target hook structure and definitions. */
73 /* ------------------------------------------------------------------------ */
75 /* PART 1: Auxiliary static variable definitions and
76 target hook static variable definitions. */
78 /* Define intrinsic register names.
79 Please refer to nds32_intrinsic.h file, the index is corresponding to
80 'enum nds32_intrinsic_registers' data type values.
81 NOTE that the base value starting from 1024. */
82 static const char * const nds32_intrinsic_register_names
[] =
240 /* Define instrinsic cctl names. */
241 static const char * const nds32_cctl_names
[] =
269 static const char * const nds32_dpref_names
[] =
279 /* Defining register allocation order for performance.
280 We want to allocate callee-saved registers after others.
281 It may be used by nds32_adjust_reg_alloc_order(). */
282 static const int nds32_reg_alloc_order_for_speed
[] =
284 0, 1, 2, 3, 4, 5, 16, 17,
285 18, 19, 20, 21, 22, 23, 24, 25,
286 26, 27, 6, 7, 8, 9, 10, 11,
290 /* Defining target-specific uses of __attribute__. */
291 static const struct attribute_spec nds32_attribute_table
[] =
293 /* Syntax: { name, min_len, max_len, decl_required, type_required,
294 function_type_required, affects_type_identity, handler,
297 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
298 { "interrupt", 1, 64, false, false, false, false, NULL
, NULL
},
299 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
300 { "exception", 1, 8, false, false, false, false, NULL
, NULL
},
301 /* Argument is user's interrupt numbers. The vector number is always 0. */
302 { "reset", 1, 1, false, false, false, false, NULL
, NULL
},
304 /* The attributes describing isr nested type. */
305 { "nested", 0, 0, false, false, false, false, NULL
, NULL
},
306 { "not_nested", 0, 0, false, false, false, false, NULL
, NULL
},
307 { "nested_ready", 0, 0, false, false, false, false, NULL
, NULL
},
309 /* The attributes describing isr register save scheme. */
310 { "save_all", 0, 0, false, false, false, false, NULL
, NULL
},
311 { "partial_save", 0, 0, false, false, false, false, NULL
, NULL
},
313 /* The attributes used by reset attribute. */
314 { "nmi", 1, 1, false, false, false, false, NULL
, NULL
},
315 { "warm", 1, 1, false, false, false, false, NULL
, NULL
},
317 /* The attribute telling no prologue/epilogue. */
318 { "naked", 0, 0, false, false, false, false, NULL
, NULL
},
320 /* The last attribute spec is set to be NULL. */
321 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
325 /* ------------------------------------------------------------------------ */
327 /* PART 2: Auxiliary static function definitions. */
329 /* Function to save and restore machine-specific function data. */
330 static struct machine_function
*
331 nds32_init_machine_status (void)
333 struct machine_function
*machine
;
334 machine
= ggc_cleared_alloc
<machine_function
> ();
336 /* Initially assume this function does not use __builtin_eh_return. */
337 machine
->use_eh_return_p
= 0;
339 /* Initially assume this function needs prologue/epilogue. */
340 machine
->naked_p
= 0;
342 /* Initially assume this function does NOT use fp_as_gp optimization. */
343 machine
->fp_as_gp_p
= 0;
345 /* Initially this function is not under strictly aligned situation. */
346 machine
->strict_aligned_p
= 0;
351 /* Function to compute stack frame size and
352 store into cfun->machine structure. */
354 nds32_compute_stack_frame (void)
360 /* Because nds32_compute_stack_frame() will be called from different place,
361 everytime we enter this function, we have to assume this function
362 needs prologue/epilogue. */
363 cfun
->machine
->naked_p
= 0;
366 /* If __builtin_eh_return is used, we better have frame pointer needed
367 so that we can easily locate the stack slot of return address. */
368 if (crtl
->calls_eh_return
)
370 frame_pointer_needed
= 1;
372 /* We need to mark eh data registers that need to be saved
374 cfun
->machine
->eh_return_data_first_regno
= EH_RETURN_DATA_REGNO (0);
375 for (r
= 0; EH_RETURN_DATA_REGNO (r
) != INVALID_REGNUM
; r
++)
376 cfun
->machine
->eh_return_data_last_regno
= r
;
378 cfun
->machine
->eh_return_data_regs_size
379 = 4 * (cfun
->machine
->eh_return_data_last_regno
380 - cfun
->machine
->eh_return_data_first_regno
382 cfun
->machine
->use_eh_return_p
= 1;
386 /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we
387 do not need to handle __builtin_eh_return case in this function. */
388 cfun
->machine
->eh_return_data_first_regno
= SP_REGNUM
;
389 cfun
->machine
->eh_return_data_last_regno
= SP_REGNUM
;
391 cfun
->machine
->eh_return_data_regs_size
= 0;
392 cfun
->machine
->use_eh_return_p
= 0;
395 /* Get variadic arguments size to prepare pretend arguments and
396 we will push them into stack at prologue by ourself. */
397 cfun
->machine
->va_args_size
= crtl
->args
.pretend_args_size
;
398 if (cfun
->machine
->va_args_size
!= 0)
400 cfun
->machine
->va_args_first_regno
401 = NDS32_GPR_ARG_FIRST_REGNUM
402 + NDS32_MAX_GPR_REGS_FOR_ARGS
403 - (crtl
->args
.pretend_args_size
/ UNITS_PER_WORD
);
404 cfun
->machine
->va_args_last_regno
405 = NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
- 1;
409 cfun
->machine
->va_args_first_regno
= SP_REGNUM
;
410 cfun
->machine
->va_args_last_regno
= SP_REGNUM
;
413 /* Important: We need to make sure that varargs area is 8-byte alignment. */
414 block_size
= cfun
->machine
->va_args_size
;
415 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
417 cfun
->machine
->va_args_area_padding_bytes
418 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
421 /* Get local variables, incoming variables, and temporary variables size.
422 Note that we need to make sure it is 8-byte alignment because
423 there may be no padding bytes if we are using LRA. */
424 cfun
->machine
->local_size
= NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
426 /* Get outgoing arguments size. */
427 cfun
->machine
->out_args_size
= crtl
->outgoing_args_size
;
429 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
430 Check whether $fp is ever live. */
431 cfun
->machine
->fp_size
= (df_regs_ever_live_p (FP_REGNUM
)) ? 4 : 0;
433 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
434 Check whether we are using PIC code genration. */
435 cfun
->machine
->gp_size
= (flag_pic
) ? 4 : 0;
437 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
438 Check whether $lp is ever live. */
439 cfun
->machine
->lp_size
440 = (flag_always_save_lp
|| df_regs_ever_live_p (LP_REGNUM
)) ? 4 : 0;
442 /* Initially there is no padding bytes. */
443 cfun
->machine
->callee_saved_area_gpr_padding_bytes
= 0;
445 /* Calculate the bytes of saving callee-saved registers on stack. */
446 cfun
->machine
->callee_saved_gpr_regs_size
= 0;
447 cfun
->machine
->callee_saved_first_gpr_regno
= SP_REGNUM
;
448 cfun
->machine
->callee_saved_last_gpr_regno
= SP_REGNUM
;
449 cfun
->machine
->callee_saved_fpr_regs_size
= 0;
450 cfun
->machine
->callee_saved_first_fpr_regno
= SP_REGNUM
;
451 cfun
->machine
->callee_saved_last_fpr_regno
= SP_REGNUM
;
453 /* Currently, there is no need to check $r28~$r31
454 because we will save them in another way. */
455 for (r
= 0; r
< 28; r
++)
457 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
459 /* Mark the first required callee-saved register
460 (only need to set it once).
461 If first regno == SP_REGNUM, we can tell that
462 it is the first time to be here. */
463 if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
464 cfun
->machine
->callee_saved_first_gpr_regno
= r
;
465 /* Mark the last required callee-saved register. */
466 cfun
->machine
->callee_saved_last_gpr_regno
= r
;
470 /* Recording fpu callee-saved register. */
471 if (TARGET_HARD_FLOAT
)
473 for (r
= NDS32_FIRST_FPR_REGNUM
; r
< NDS32_LAST_FPR_REGNUM
; r
++)
475 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
477 /* Mark the first required callee-saved register. */
478 if (cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
)
480 /* Make first callee-saved number is even,
481 bacause we use doubleword access, and this way
482 promise 8-byte alignemt. */
483 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r
))
484 cfun
->machine
->callee_saved_first_fpr_regno
= r
- 1;
486 cfun
->machine
->callee_saved_first_fpr_regno
= r
;
488 cfun
->machine
->callee_saved_last_fpr_regno
= r
;
492 /* Make last callee-saved register number is odd,
493 we hope callee-saved register is even. */
494 int last_fpr
= cfun
->machine
->callee_saved_last_fpr_regno
;
495 if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr
))
496 cfun
->machine
->callee_saved_last_fpr_regno
++;
499 /* Check if this function can omit prologue/epilogue code fragment.
500 If there is 'naked' attribute in this function,
501 we can set 'naked_p' flag to indicate that
502 we do not have to generate prologue/epilogue.
503 Or, if all the following conditions succeed,
504 we can set this function 'naked_p' as well:
505 condition 1: first_regno == last_regno == SP_REGNUM,
506 which means we do not have to save
507 any callee-saved registers.
508 condition 2: Both $lp and $fp are NOT live in this function,
509 which means we do not need to save them and there
511 condition 3: There is no local_size, which means
512 we do not need to adjust $sp. */
513 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
))
514 || (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
515 && cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
516 && cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
517 && cfun
->machine
->callee_saved_last_fpr_regno
== SP_REGNUM
518 && !df_regs_ever_live_p (FP_REGNUM
)
519 && !df_regs_ever_live_p (LP_REGNUM
)
520 && cfun
->machine
->local_size
== 0))
522 /* Set this function 'naked_p' and other functions can check this flag.
523 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
524 callee-saved, local size, and outgoing size.
525 The varargs space and ret instruction may still present in
526 the prologue/epilogue expanding. */
527 cfun
->machine
->naked_p
= 1;
529 /* No need to save $fp, $gp, and $lp.
530 We should set these value to be zero
531 so that nds32_initial_elimination_offset() can work properly. */
532 cfun
->machine
->fp_size
= 0;
533 cfun
->machine
->gp_size
= 0;
534 cfun
->machine
->lp_size
= 0;
536 /* If stack usage computation is required,
537 we need to provide the static stack size. */
538 if (flag_stack_usage_info
)
539 current_function_static_stack_size
= 0;
541 /* No need to do following adjustment, return immediately. */
545 v3pushpop_p
= NDS32_V3PUSH_AVAILABLE_P
;
547 /* Adjustment for v3push instructions:
548 If we are using v3push (push25/pop25) instructions,
549 we need to make sure Rb is $r6 and Re is
550 located on $r6, $r8, $r10, or $r14.
551 Some results above will be discarded and recomputed.
552 Note that it is only available under V3/V3M ISA and we
553 DO NOT setup following stuff for isr or variadic function. */
557 cfun->machine->fp_size
558 cfun->machine->gp_size
559 cfun->machine->lp_size
560 cfun->machine->callee_saved_first_gpr_regno
561 cfun->machine->callee_saved_last_gpr_regno */
563 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
564 cfun
->machine
->fp_size
= 4;
565 cfun
->machine
->gp_size
= 4;
566 cfun
->machine
->lp_size
= 4;
568 /* Remember to set Rb = $r6. */
569 cfun
->machine
->callee_saved_first_gpr_regno
= 6;
571 if (cfun
->machine
->callee_saved_last_gpr_regno
<= 6)
574 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
576 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 8)
579 cfun
->machine
->callee_saved_last_gpr_regno
= 8;
581 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 10)
584 cfun
->machine
->callee_saved_last_gpr_regno
= 10;
586 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 14)
589 cfun
->machine
->callee_saved_last_gpr_regno
= 14;
591 else if (cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
)
593 /* If last_regno is SP_REGNUM, which means
594 it is never changed, so set it to Re = $r6. */
595 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
599 /* The program flow should not go here. */
604 int sp_adjust
= cfun
->machine
->local_size
605 + cfun
->machine
->out_args_size
606 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
607 + cfun
->machine
->callee_saved_fpr_regs_size
;
611 && !frame_pointer_needed
)
613 block_size
= cfun
->machine
->fp_size
614 + cfun
->machine
->gp_size
615 + cfun
->machine
->lp_size
;
617 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
618 block_size
+= (4 * (cfun
->machine
->callee_saved_last_gpr_regno
619 - cfun
->machine
->callee_saved_first_gpr_regno
622 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
624 /* $r14 is last callee save register. */
625 if (cfun
->machine
->callee_saved_last_gpr_regno
626 < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM
)
628 cfun
->machine
->callee_saved_last_gpr_regno
++;
630 else if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
632 cfun
->machine
->callee_saved_first_gpr_regno
633 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
634 cfun
->machine
->callee_saved_last_gpr_regno
635 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
640 /* We have correctly set callee_saved_first_gpr_regno
641 and callee_saved_last_gpr_regno.
642 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
643 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
644 we can update callee_saved_gpr_regs_size with new size. */
645 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
647 /* Compute pushed size of callee-saved registers. */
648 cfun
->machine
->callee_saved_gpr_regs_size
649 = 4 * (cfun
->machine
->callee_saved_last_gpr_regno
650 - cfun
->machine
->callee_saved_first_gpr_regno
654 if (TARGET_HARD_FLOAT
)
656 /* Compute size of callee svaed floating-point registers. */
657 if (cfun
->machine
->callee_saved_last_fpr_regno
!= SP_REGNUM
)
659 cfun
->machine
->callee_saved_fpr_regs_size
660 = 4 * (cfun
->machine
->callee_saved_last_fpr_regno
661 - cfun
->machine
->callee_saved_first_fpr_regno
666 /* Important: We need to make sure that
667 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
669 If it is not, calculate the padding bytes. */
670 block_size
= cfun
->machine
->fp_size
671 + cfun
->machine
->gp_size
672 + cfun
->machine
->lp_size
673 + cfun
->machine
->callee_saved_gpr_regs_size
;
674 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
676 cfun
->machine
->callee_saved_area_gpr_padding_bytes
677 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
680 /* If stack usage computation is required,
681 we need to provide the static stack size. */
682 if (flag_stack_usage_info
)
684 current_function_static_stack_size
685 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
)
686 + cfun
->machine
->local_size
687 + cfun
->machine
->out_args_size
;
691 /* Function to create a parallel rtx pattern
692 which presents stack push multiple behavior.
693 The overall concept are:
694 "push registers to memory",
695 "adjust stack pointer". */
697 nds32_emit_stack_push_multiple (unsigned Rb
, unsigned Re
,
698 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
,
714 /* We need to provide a customized rtx which contains
715 necessary information for data analysis,
716 so we create a parallel rtx like this:
717 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
719 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
722 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
724 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
726 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
728 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
730 (set (reg:SI SP_REGNUM)
731 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
733 /* Calculate the number of registers that will be pushed. */
741 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
742 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
743 num_use_regs
= extra_count
;
745 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
747 /* In addition to used registers,
748 we need one more space for (set sp sp-x) rtx. */
749 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
750 rtvec_alloc (num_use_regs
+ 1));
753 /* Initialize offset and start to create push behavior. */
754 offset
= -(num_use_regs
* 4);
756 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
757 for (regno
= Rb
; regno
<= Re
; regno
++)
759 /* Rb and Re may be SP_REGNUM.
760 We need to break this loop immediately. */
761 if (regno
== SP_REGNUM
)
764 reg
= gen_rtx_REG (SImode
, regno
);
765 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
768 push_rtx
= gen_rtx_SET (mem
, reg
);
769 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
770 RTX_FRAME_RELATED_P (push_rtx
) = 1;
775 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
778 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
779 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
782 push_rtx
= gen_rtx_SET (mem
, reg
);
783 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
784 RTX_FRAME_RELATED_P (push_rtx
) = 1;
790 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
791 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
794 push_rtx
= gen_rtx_SET (mem
, reg
);
795 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
796 RTX_FRAME_RELATED_P (push_rtx
) = 1;
802 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
803 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
806 push_rtx
= gen_rtx_SET (mem
, reg
);
807 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
808 RTX_FRAME_RELATED_P (push_rtx
) = 1;
813 /* Create (set sp sp-x). */
815 /* We need to re-calculate the offset value again for adjustment. */
816 offset
= -(num_use_regs
* 4);
818 = gen_rtx_SET (stack_pointer_rtx
,
819 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
820 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
821 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
823 parallel_insn
= emit_insn (parallel_insn
);
825 /* The insn rtx 'parallel_insn' will change frame layout.
826 We need to use RTX_FRAME_RELATED_P so that GCC is able to
827 generate CFI (Call Frame Information) stuff. */
828 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
830 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
831 since we will not restore those register at epilogue. */
834 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
835 copy_rtx (adjust_sp_rtx
), NULL_RTX
);
836 REG_NOTES (parallel_insn
) = dwarf
;
840 /* Function to create a parallel rtx pattern
841 which presents stack pop multiple behavior.
842 The overall concept are:
843 "pop registers from memory",
844 "adjust stack pointer". */
846 nds32_emit_stack_pop_multiple (unsigned Rb
, unsigned Re
,
847 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
)
860 rtx dwarf
= NULL_RTX
;
862 /* We need to provide a customized rtx which contains
863 necessary information for data analysis,
864 so we create a parallel rtx like this:
865 (parallel [(set (reg:SI Rb)
866 (mem (reg:SI SP_REGNUM)))
868 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
871 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
872 (set (reg:SI FP_REGNUM)
873 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
874 (set (reg:SI GP_REGNUM)
875 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
876 (set (reg:SI LP_REGNUM)
877 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
878 (set (reg:SI SP_REGNUM)
879 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
881 /* Calculate the number of registers that will be poped. */
889 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
890 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
891 num_use_regs
= extra_count
;
893 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
895 /* In addition to used registers,
896 we need one more space for (set sp sp+x) rtx. */
897 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
898 rtvec_alloc (num_use_regs
+ 1));
901 /* Initialize offset and start to create pop behavior. */
904 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
905 for (regno
= Rb
; regno
<= Re
; regno
++)
907 /* Rb and Re may be SP_REGNUM.
908 We need to break this loop immediately. */
909 if (regno
== SP_REGNUM
)
912 reg
= gen_rtx_REG (SImode
, regno
);
913 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
916 pop_rtx
= gen_rtx_SET (reg
, mem
);
917 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
918 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
922 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
925 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
928 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
929 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
932 pop_rtx
= gen_rtx_SET (reg
, mem
);
933 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
934 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
938 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
942 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
943 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
946 pop_rtx
= gen_rtx_SET (reg
, mem
);
947 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
948 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
952 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
956 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
957 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
960 pop_rtx
= gen_rtx_SET (reg
, mem
);
961 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
962 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
966 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
969 /* Create (set sp sp+x). */
971 /* The offset value is already in place. No need to re-calculate it. */
973 = gen_rtx_SET (stack_pointer_rtx
,
974 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
975 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
977 /* Tell gcc we adjust SP in this insn. */
978 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
980 parallel_insn
= emit_insn (parallel_insn
);
982 /* The insn rtx 'parallel_insn' will change frame layout.
983 We need to use RTX_FRAME_RELATED_P so that GCC is able to
984 generate CFI (Call Frame Information) stuff. */
985 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
987 /* Add CFI info by manual. */
988 REG_NOTES (parallel_insn
) = dwarf
;
991 /* Function to create a parallel rtx pattern
992 which presents stack v3push behavior.
993 The overall concept are:
994 "push registers to memory",
995 "adjust stack pointer". */
997 nds32_emit_stack_v3push (unsigned Rb
,
1012 /* We need to provide a customized rtx which contains
1013 necessary information for data analysis,
1014 so we create a parallel rtx like this:
1015 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
1017 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
1020 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
1022 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
1024 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
1026 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
1028 (set (reg:SI SP_REGNUM)
1029 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
1031 /* Calculate the number of registers that will be pushed.
1032 Since $fp, $gp, and $lp is always pushed with v3push instruction,
1033 we need to count these three registers.
1034 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1035 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1036 num_use_regs
= Re
- Rb
+ 1 + 3;
1038 /* In addition to used registers,
1039 we need one more space for (set sp sp-x-imm8u) rtx. */
1040 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1041 rtvec_alloc (num_use_regs
+ 1));
1044 /* Initialize offset and start to create push behavior. */
1045 offset
= -(num_use_regs
* 4);
1047 /* Create (set mem regX) from Rb, Rb+1 up to Re.
1048 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1049 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1050 for (regno
= Rb
; regno
<= Re
; regno
++)
1052 reg
= gen_rtx_REG (SImode
, regno
);
1053 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1056 push_rtx
= gen_rtx_SET (mem
, reg
);
1057 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1058 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1059 offset
= offset
+ 4;
1063 /* Create (set mem fp). */
1064 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1065 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1068 push_rtx
= gen_rtx_SET (mem
, reg
);
1069 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1070 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1071 offset
= offset
+ 4;
1073 /* Create (set mem gp). */
1074 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1075 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1078 push_rtx
= gen_rtx_SET (mem
, reg
);
1079 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1080 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1081 offset
= offset
+ 4;
1083 /* Create (set mem lp). */
1084 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1085 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1088 push_rtx
= gen_rtx_SET (mem
, reg
);
1089 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1090 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1091 offset
= offset
+ 4;
1094 /* Create (set sp sp-x-imm8u). */
1096 /* We need to re-calculate the offset value again for adjustment. */
1097 offset
= -(num_use_regs
* 4);
1099 = gen_rtx_SET (stack_pointer_rtx
,
1100 plus_constant (Pmode
,
1103 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1104 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
1106 parallel_insn
= emit_insn (parallel_insn
);
1108 /* The insn rtx 'parallel_insn' will change frame layout.
1109 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1110 generate CFI (Call Frame Information) stuff. */
1111 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1114 /* Function to create a parallel rtx pattern
1115 which presents stack v3pop behavior.
1116 The overall concept are:
1117 "pop registers from memory",
1118 "adjust stack pointer". */
1120 nds32_emit_stack_v3pop (unsigned Rb
,
1134 rtx dwarf
= NULL_RTX
;
1136 /* We need to provide a customized rtx which contains
1137 necessary information for data analysis,
1138 so we create a parallel rtx like this:
1139 (parallel [(set (reg:SI Rb)
1140 (mem (reg:SI SP_REGNUM)))
1142 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
1145 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
1146 (set (reg:SI FP_REGNUM)
1147 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
1148 (set (reg:SI GP_REGNUM)
1149 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
1150 (set (reg:SI LP_REGNUM)
1151 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
1152 (set (reg:SI SP_REGNUM)
1153 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
1155 /* Calculate the number of registers that will be poped.
1156 Since $fp, $gp, and $lp is always poped with v3pop instruction,
1157 we need to count these three registers.
1158 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1159 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1160 num_use_regs
= Re
- Rb
+ 1 + 3;
1162 /* In addition to used registers,
1163 we need one more space for (set sp sp+x+imm8u) rtx. */
1164 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1165 rtvec_alloc (num_use_regs
+ 1));
1168 /* Initialize offset and start to create pop behavior. */
1171 /* Create (set regX mem) from Rb, Rb+1 up to Re.
1172 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1173 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1174 for (regno
= Rb
; regno
<= Re
; regno
++)
1176 reg
= gen_rtx_REG (SImode
, regno
);
1177 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1180 pop_rtx
= gen_rtx_SET (reg
, mem
);
1181 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1182 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1183 offset
= offset
+ 4;
1186 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1189 /* Create (set fp mem). */
1190 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1191 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1194 pop_rtx
= gen_rtx_SET (reg
, mem
);
1195 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1196 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1197 offset
= offset
+ 4;
1199 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1201 /* Create (set gp mem). */
1202 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1203 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1206 pop_rtx
= gen_rtx_SET (reg
, mem
);
1207 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1208 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1209 offset
= offset
+ 4;
1211 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1213 /* Create (set lp mem ). */
1214 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1215 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1218 pop_rtx
= gen_rtx_SET (reg
, mem
);
1219 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1220 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1221 offset
= offset
+ 4;
1223 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1225 /* Create (set sp sp+x+imm8u). */
1227 /* The offset value is already in place. No need to re-calculate it. */
1229 = gen_rtx_SET (stack_pointer_rtx
,
1230 plus_constant (Pmode
,
1233 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1235 if (frame_pointer_needed
)
1237 /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp)
1239 mean reset frame pointer to $sp and reset to offset 0. */
1240 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
1242 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
1246 /* Tell gcc we adjust SP in this insn. */
1247 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
1248 copy_rtx (adjust_sp_rtx
), dwarf
);
1251 parallel_insn
= emit_insn (parallel_insn
);
1253 /* The insn rtx 'parallel_insn' will change frame layout.
1254 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1255 generate CFI (Call Frame Information) stuff. */
1256 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1258 /* Add CFI info by manual. */
1259 REG_NOTES (parallel_insn
) = dwarf
;
1262 /* Function that may creates more instructions
1263 for large value on adjusting stack pointer.
1265 In nds32 target, 'addi' can be used for stack pointer
1266 adjustment in prologue/epilogue stage.
1267 However, sometimes there are too many local variables so that
1268 the adjustment value is not able to be fit in the 'addi' instruction.
1269 One solution is to move value into a register
1270 and then use 'add' instruction.
1271 In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */
1273 nds32_emit_adjust_frame (rtx to_reg
, rtx from_reg
, int adjust_value
)
1276 rtx frame_adjust_insn
;
1277 rtx adjust_value_rtx
= GEN_INT (adjust_value
);
1279 if (adjust_value
== 0)
1282 if (!satisfies_constraint_Is15 (adjust_value_rtx
))
1284 /* The value is not able to fit in single addi instruction.
1285 Create more instructions of moving value into a register
1286 and then add stack pointer with it. */
1288 /* $r15 is going to be temporary register to hold the value. */
1289 tmp_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
1291 /* Create one more instruction to move value
1292 into the temporary register. */
1293 emit_move_insn (tmp_reg
, adjust_value_rtx
);
1295 /* Create new 'add' rtx. */
1296 frame_adjust_insn
= gen_addsi3 (to_reg
,
1299 /* Emit rtx into insn list and receive its transformed insn rtx. */
1300 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1302 /* Because (tmp_reg <- full_value) may be split into two
1303 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1304 We need to construct another (sp <- sp + full_value)
1305 and then insert it into sp_adjust_insn's reg note to
1306 represent a frame related expression.
1307 GCC knows how to refer it and output debug information. */
1312 plus_rtx
= plus_constant (Pmode
, from_reg
, adjust_value
);
1313 set_rtx
= gen_rtx_SET (to_reg
, plus_rtx
);
1314 add_reg_note (frame_adjust_insn
, REG_FRAME_RELATED_EXPR
, set_rtx
);
1318 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
1319 frame_adjust_insn
= gen_addsi3 (to_reg
,
1322 /* Emit rtx into instructions list and receive INSN rtx form. */
1323 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1326 /* The insn rtx 'sp_adjust_insn' will change frame layout.
1327 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1328 generate CFI (Call Frame Information) stuff. */
1329 RTX_FRAME_RELATED_P (frame_adjust_insn
) = 1;
1332 /* Return true if MODE/TYPE need double word alignment. */
1334 nds32_needs_double_word_align (machine_mode mode
, const_tree type
)
1338 /* Pick up the alignment according to the mode or type. */
1339 align
= NDS32_MODE_TYPE_ALIGN (mode
, type
);
1341 return (align
> PARM_BOUNDARY
);
1344 /* Return true if FUNC is a naked function. */
1346 nds32_naked_function_p (tree func
)
1350 if (TREE_CODE (func
) != FUNCTION_DECL
)
1353 t
= lookup_attribute ("naked", DECL_ATTRIBUTES (func
));
1355 return (t
!= NULL_TREE
);
1358 /* Function that determine whether a load postincrement is a good thing to use
1359 for a given mode. */
1361 nds32_use_load_post_increment (machine_mode mode
)
1363 return (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE(E_DImode
));
1366 /* Function that check if 'X' is a valid address register.
1367 The variable 'STRICT' is very important to
1368 make decision for register number.
1371 => We are in reload pass or after reload pass.
1372 The register number should be strictly limited in general registers.
1375 => Before reload pass, we are free to use any register number. */
1377 nds32_address_register_rtx_p (rtx x
, bool strict
)
1381 if (GET_CODE (x
) != REG
)
1387 return REGNO_OK_FOR_BASE_P (regno
);
1392 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1394 OUTER_MODE : Machine mode of outer address rtx.
1395 INDEX : Check if this rtx is valid to be a index for address.
1396 STRICT : If it is true, we are in reload pass or after reload pass. */
1398 nds32_legitimate_index_p (machine_mode outer_mode
,
1406 switch (GET_CODE (index
))
1409 regno
= REGNO (index
);
1410 /* If we are in reload pass or after reload pass,
1411 we need to limit it to general register. */
1413 return REGNO_OK_FOR_INDEX_P (regno
);
1418 /* The alignment of the integer value is determined by 'outer_mode'. */
1419 switch (GET_MODE_SIZE (outer_mode
))
1422 /* Further check if the value is legal for the 'outer_mode'. */
1423 if (satisfies_constraint_Is15 (index
))
1428 /* Further check if the value is legal for the 'outer_mode'. */
1429 if (satisfies_constraint_Is16 (index
))
1431 /* If it is not under strictly aligned situation,
1432 we can return true without checking alignment. */
1433 if (!cfun
->machine
->strict_aligned_p
)
1435 /* Make sure address is half word alignment. */
1436 else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index
)))
1442 /* Further check if the value is legal for the 'outer_mode'. */
1443 if (satisfies_constraint_Is17 (index
))
1445 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1447 if (!satisfies_constraint_Is14 (index
))
1451 /* If it is not under strictly aligned situation,
1452 we can return true without checking alignment. */
1453 if (!cfun
->machine
->strict_aligned_p
)
1455 /* Make sure address is word alignment. */
1456 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1462 if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index
) + 4,
1465 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1467 if (!satisfies_constraint_Is14 (index
))
1471 /* If it is not under strictly aligned situation,
1472 we can return true without checking alignment. */
1473 if (!cfun
->machine
->strict_aligned_p
)
1475 /* Make sure address is word alignment.
1476 Currently we do not have 64-bit load/store yet,
1477 so we will use two 32-bit load/store instructions to do
1478 memory access and they are single word alignment. */
1479 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1491 op0
= XEXP (index
, 0);
1492 op1
= XEXP (index
, 1);
1494 if (REG_P (op0
) && CONST_INT_P (op1
))
1497 multiplier
= INTVAL (op1
);
1499 /* We only allow (mult reg const_int_1), (mult reg const_int_2),
1500 (mult reg const_int_4) or (mult reg const_int_8). */
1501 if (multiplier
!= 1 && multiplier
!= 2
1502 && multiplier
!= 4 && multiplier
!= 8)
1505 regno
= REGNO (op0
);
1506 /* Limit it in general registers if we are
1507 in reload pass or after reload pass. */
1509 return REGNO_OK_FOR_INDEX_P (regno
);
1517 op0
= XEXP (index
, 0);
1518 op1
= XEXP (index
, 1);
1520 if (REG_P (op0
) && CONST_INT_P (op1
))
1523 /* op1 is already the sv value for use to do left shift. */
1526 /* We only allow (ashift reg const_int_0)
1527 or (ashift reg const_int_1) or (ashift reg const_int_2) or
1528 (ashift reg const_int_3). */
1529 if (sv
!= 0 && sv
!= 1 && sv
!=2 && sv
!= 3)
1532 regno
= REGNO (op0
);
1533 /* Limit it in general registers if we are
1534 in reload pass or after reload pass. */
1536 return REGNO_OK_FOR_INDEX_P (regno
);
1549 nds32_register_pass (
1550 rtl_opt_pass
*(*make_pass_func
) (gcc::context
*),
1551 enum pass_positioning_ops pass_pos
,
1552 const char *ref_pass_name
)
1554 opt_pass
*new_opt_pass
= make_pass_func (g
);
1556 struct register_pass_info insert_pass
=
1558 new_opt_pass
, /* pass */
1559 ref_pass_name
, /* reference_pass_name */
1560 1, /* ref_pass_instance_number */
1561 pass_pos
/* po_op */
1564 register_pass (&insert_pass
);
1567 /* This function is called from nds32_option_override ().
1568 All new passes should be registered here. */
1570 nds32_register_passes (void)
1572 nds32_register_pass (
1573 make_pass_nds32_relax_opt
,
1574 PASS_POS_INSERT_AFTER
,
1578 /* ------------------------------------------------------------------------ */
1580 /* PART 3: Implement target hook stuff definitions. */
1583 /* Computing the Length of an Insn.
1584 Modifies the length assigned to instruction INSN.
1585 LEN is the initially computed length of the insn. */
1587 nds32_adjust_insn_length (rtx_insn
*insn
, int length
)
1589 int adjust_value
= 0;
1590 switch (recog_memoized (insn
))
1592 case CODE_FOR_call_internal
:
1593 case CODE_FOR_call_value_internal
:
1595 if (NDS32_ALIGN_P ())
1597 rtx_insn
*next_insn
= next_active_insn (insn
);
1598 if (next_insn
&& get_attr_length (next_insn
) != 2)
1601 /* We need insert a nop after a noretun function call
1602 to prevent software breakpoint corrupt the next function. */
1603 if (find_reg_note (insn
, REG_NORETURN
, NULL_RTX
))
1611 return length
+ adjust_value
;
1618 /* Storage Layout. */
1620 /* This function will be called just before expansion into rtl. */
1622 nds32_expand_to_rtl_hook (void)
1624 /* We need to set strictly aligned situation.
1625 After that, the memory address checking in nds32_legitimate_address_p()
1626 will take alignment offset into consideration so that it will not create
1627 unaligned [base + offset] access during the rtl optimization. */
1628 cfun
->machine
->strict_aligned_p
= 1;
1632 /* Register Usage. */
1635 nds32_conditional_register_usage (void)
1639 if (TARGET_HARD_FLOAT
)
1641 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1642 regno
<= NDS32_LAST_FPR_REGNUM
; regno
++)
1644 fixed_regs
[regno
] = 0;
1645 if (regno
< NDS32_FIRST_FPR_REGNUM
+ NDS32_MAX_FPR_REGS_FOR_ARGS
)
1646 call_used_regs
[regno
] = 1;
1647 else if (regno
>= NDS32_FIRST_FPR_REGNUM
+ 22
1648 && regno
< NDS32_FIRST_FPR_REGNUM
+ 48)
1649 call_used_regs
[regno
] = 1;
1651 call_used_regs
[regno
] = 0;
1654 else if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1656 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1657 regno
<= NDS32_LAST_FPR_REGNUM
;
1659 fixed_regs
[regno
] = 0;
1664 /* Register Classes. */
1666 static unsigned char
1667 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED
,
1670 /* Return the maximum number of consecutive registers
1671 needed to represent "mode" in a register of "rclass". */
1672 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
1676 nds32_register_priority (int hard_regno
)
1678 /* Encourage to use r0-r7 for LRA when optimize for size. */
1683 else if (hard_regno
< 16)
1685 else if (hard_regno
< 28)
1692 if (hard_regno
> 27)
1700 nds32_can_change_mode_class (machine_mode from
,
1704 /* Don't spill double-precision register to two singal-precision
1706 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1707 && GET_MODE_SIZE (from
) != GET_MODE_SIZE (to
))
1709 return !reg_classes_intersect_p (rclass
, FP_REGS
);
1716 /* Stack Layout and Calling Conventions. */
1718 /* There are three kinds of pointer concepts using in GCC compiler:
1720 frame pointer: A pointer to the first location of local variables.
1721 stack pointer: A pointer to the top of a stack frame.
1722 argument pointer: A pointer to the incoming arguments.
1724 In nds32 target calling convention, we are using 8-byte alignment.
1725 Besides, we would like to have each stack frame of a function includes:
1728 1. previous hard frame pointer
1730 3. callee-saved registers
1731 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1733 cfun->machine->callee_saved_area_padding_bytes)
1737 2. spilling location
1738 3. <padding bytes> (it will be calculated by GCC itself)
1739 4. incoming arguments
1740 5. <padding bytes> (it will be calculated by GCC itself)
1743 1. <padding bytes> (it will be calculated by GCC itself)
1744 2. outgoing arguments
1746 We 'wrap' these blocks together with
1747 hard frame pointer ($r28) and stack pointer ($r31).
1748 By applying the basic frame/stack/argument pointers concept,
1749 the layout of a stack frame shoule be like this:
1752 old stack pointer -> ----
1754 | | saved arguments for
1755 | | vararg functions
1757 hard frame pointer -> --
1758 & argument pointer | | \
1759 | | previous hardware frame pointer
1761 | | callee-saved registers
1766 | | and incoming arguments
1773 stack pointer -> ----
1775 $SFP and $AP are used to represent frame pointer and arguments pointer,
1776 which will be both eliminated as hard frame pointer. */
1778 /* -- Eliminating Frame Pointer and Arg Pointer. */
1781 nds32_can_eliminate (const int from_reg
, const int to_reg
)
1783 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1786 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1789 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1792 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1798 /* -- Passing Arguments in Registers. */
1801 nds32_function_arg (cumulative_args_t ca
, machine_mode mode
,
1802 const_tree type
, bool named
)
1805 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1807 /* The last time this hook is called,
1808 it is called with MODE == VOIDmode. */
1809 if (mode
== VOIDmode
)
1812 /* For nameless arguments, we need to take care it individually. */
1815 /* If we are under hard float abi, we have arguments passed on the
1816 stack and all situation can be handled by GCC itself. */
1817 if (TARGET_HARD_FLOAT
)
1820 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1822 /* If we still have enough registers to pass argument, pick up
1823 next available register number. */
1825 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1826 return gen_rtx_REG (mode
, regno
);
1829 /* No register available, return NULL_RTX.
1830 The compiler will use stack to pass argument instead. */
1834 /* The following is to handle named argument.
1835 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1837 if (TARGET_HARD_FLOAT
)
1839 /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR
1840 to pass argument. We have to further check TYPE and MODE so
1841 that we can determine which kind of register we shall use. */
1843 /* Note that we need to pass argument entirely in registers under
1845 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1846 && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum
->fpr_offset
, mode
, type
))
1848 /* Pick up the next available FPR register number. */
1850 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
);
1851 return gen_rtx_REG (mode
, regno
);
1853 else if (GET_MODE_CLASS (mode
) != MODE_FLOAT
1854 && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1856 /* Pick up the next available GPR register number. */
1858 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1859 return gen_rtx_REG (mode
, regno
);
1864 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1865 argument. Since we allow to pass argument partially in registers,
1866 we can just return it if there are still registers available. */
1867 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1869 /* Pick up the next available register number. */
1871 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1872 return gen_rtx_REG (mode
, regno
);
1877 /* No register available, return NULL_RTX.
1878 The compiler will use stack to pass argument instead. */
1883 nds32_must_pass_in_stack (machine_mode mode
, const_tree type
)
1885 /* Return true if a type must be passed in memory.
1886 If it is NOT using hard float abi, small aggregates can be
1887 passed in a register even we are calling a variadic function.
1888 So there is no need to take padding into consideration. */
1889 if (TARGET_HARD_FLOAT
)
1890 return must_pass_in_stack_var_size_or_pad (mode
, type
);
1892 return must_pass_in_stack_var_size (mode
, type
);
1896 nds32_arg_partial_bytes (cumulative_args_t ca
, machine_mode mode
,
1897 tree type
, bool named ATTRIBUTE_UNUSED
)
1899 /* Returns the number of bytes at the beginning of an argument that
1900 must be put in registers. The value must be zero for arguments that are
1901 passed entirely in registers or that are entirely pushed on the stack.
1902 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1903 first register to be used by the caller for this argument. */
1904 unsigned int needed_reg_count
;
1905 unsigned int remaining_reg_count
;
1906 CUMULATIVE_ARGS
*cum
;
1908 cum
= get_cumulative_args (ca
);
1910 /* Under hard float abi, we better have argument entirely passed in
1911 registers or pushed on the stack so that we can reduce the complexity
1912 of dealing with cum->gpr_offset and cum->fpr_offset. */
1913 if (TARGET_HARD_FLOAT
)
1916 /* If we have already runned out of argument registers, return zero
1917 so that the argument will be entirely pushed on the stack. */
1918 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1919 >= NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
)
1922 /* Calculate how many registers do we need for this argument. */
1923 needed_reg_count
= NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1925 /* Calculate how many argument registers have left for passing argument.
1926 Note that we should count it from next available register number. */
1928 = NDS32_MAX_GPR_REGS_FOR_ARGS
1929 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1930 - NDS32_GPR_ARG_FIRST_REGNUM
);
1932 /* Note that we have to return the nubmer of bytes, not registers count. */
1933 if (needed_reg_count
> remaining_reg_count
)
1934 return remaining_reg_count
* UNITS_PER_WORD
;
1940 nds32_function_arg_advance (cumulative_args_t ca
, machine_mode mode
,
1941 const_tree type
, bool named
)
1943 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1947 /* We need to further check TYPE and MODE so that we can determine
1948 which kind of register we shall advance. */
1950 /* Under hard float abi, we may advance FPR registers. */
1951 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1954 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
)
1955 - NDS32_FPR_ARG_FIRST_REGNUM
1956 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1961 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1962 - NDS32_GPR_ARG_FIRST_REGNUM
1963 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1968 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1969 we can advance next register as well so that caller is
1970 able to pass arguments in registers and callee must be
1971 in charge of pushing all of them into stack. */
1972 if (!TARGET_HARD_FLOAT
)
1975 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1976 - NDS32_GPR_ARG_FIRST_REGNUM
1977 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1983 nds32_function_arg_boundary (machine_mode mode
, const_tree type
)
1985 return (nds32_needs_double_word_align (mode
, type
)
1986 ? NDS32_DOUBLE_WORD_ALIGNMENT
1990 /* -- How Scalar Function Values Are Returned. */
1993 nds32_function_value (const_tree ret_type
,
1994 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1995 bool outgoing ATTRIBUTE_UNUSED
)
2000 mode
= TYPE_MODE (ret_type
);
2001 unsignedp
= TYPE_UNSIGNED (ret_type
);
2003 if (INTEGRAL_TYPE_P (ret_type
))
2004 mode
= promote_mode (ret_type
, mode
, &unsignedp
);
2006 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2007 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2009 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2013 nds32_libcall_value (machine_mode mode
,
2014 const_rtx fun ATTRIBUTE_UNUSED
)
2016 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2017 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2019 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2023 nds32_function_value_regno_p (const unsigned int regno
)
2025 if (regno
== NDS32_GPR_RET_FIRST_REGNUM
2026 || (TARGET_HARD_FLOAT
2027 && regno
== NDS32_FPR_RET_FIRST_REGNUM
))
2033 /* -- How Large Values Are Returned. */
2036 nds32_return_in_memory (const_tree type
,
2037 const_tree fntype ATTRIBUTE_UNUSED
)
2039 /* Note that int_size_in_bytes can return -1 if the size can vary
2040 or is larger than an integer. */
2041 HOST_WIDE_INT size
= int_size_in_bytes (type
);
2043 /* For COMPLEX_TYPE, if the total size cannot be hold within two registers,
2044 the return value is supposed to be in memory. We need to be aware of
2045 that the size may be -1. */
2046 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2047 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2050 /* If it is BLKmode and the total size cannot be hold within two registers,
2051 the return value is supposed to be in memory. We need to be aware of
2052 that the size may be -1. */
2053 if (TYPE_MODE (type
) == BLKmode
)
2054 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2057 /* For other cases, having result in memory is unnecessary. */
2061 /* -- Function Entry and Exit. */
2063 /* The content produced from this function
2064 will be placed before prologue body. */
2066 nds32_asm_function_prologue (FILE *file
)
2069 const char *func_name
;
2073 /* All stack frame information is supposed to be
2074 already computed when expanding prologue.
2075 The result is in cfun->machine.
2076 DO NOT call nds32_compute_stack_frame() here
2077 because it may corrupt the essential information. */
2079 fprintf (file
, "\t! BEGIN PROLOGUE\n");
2080 fprintf (file
, "\t! fp needed: %d\n", frame_pointer_needed
);
2081 fprintf (file
, "\t! pretend_args: %d\n", cfun
->machine
->va_args_size
);
2082 fprintf (file
, "\t! local_size: %d\n", cfun
->machine
->local_size
);
2083 fprintf (file
, "\t! out_args_size: %d\n", cfun
->machine
->out_args_size
);
2085 /* Use df_regs_ever_live_p() to detect if the register
2086 is ever used in the current function. */
2087 fprintf (file
, "\t! registers ever_live: ");
2088 for (r
= 0; r
< 65; r
++)
2090 if (df_regs_ever_live_p (r
))
2091 fprintf (file
, "%s, ", reg_names
[r
]);
2095 /* Display the attributes of this function. */
2096 fprintf (file
, "\t! function attributes: ");
2097 /* Get the attributes tree list.
2098 Note that GCC builds attributes list with reverse order. */
2099 attrs
= DECL_ATTRIBUTES (current_function_decl
);
2101 /* If there is no any attribute, print out "None". */
2103 fprintf (file
, "None");
2105 /* If there are some attributes, try if we need to
2106 construct isr vector information. */
2107 func_name
= IDENTIFIER_POINTER (DECL_NAME (current_function_decl
));
2108 nds32_construct_isr_vectors_information (attrs
, func_name
);
2110 /* Display all attributes of this function. */
2113 name
= TREE_PURPOSE (attrs
);
2114 fprintf (file
, "%s ", IDENTIFIER_POINTER (name
));
2116 /* Pick up the next attribute. */
2117 attrs
= TREE_CHAIN (attrs
);
2122 /* After rtl prologue has been expanded, this function is used. */
2124 nds32_asm_function_end_prologue (FILE *file
)
2126 fprintf (file
, "\t! END PROLOGUE\n");
2128 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2129 we can generate special directive: ".omit_fp_begin"
2130 to guide linker doing fp-as-gp optimization.
2131 However, for a naked function, which means
2132 it should not have prologue/epilogue,
2133 using fp-as-gp still requires saving $fp by push/pop behavior and
2134 there is no benefit to use fp-as-gp on such small function.
2135 So we need to make sure this function is NOT naked as well. */
2136 if (!frame_pointer_needed
2137 && !cfun
->machine
->naked_p
2138 && cfun
->machine
->fp_as_gp_p
)
2140 fprintf (file
, "\t! ----------------------------------------\n");
2141 fprintf (file
, "\t! Guide linker to do "
2142 "link time optimization: fp-as-gp\n");
2143 fprintf (file
, "\t! We add one more instruction to "
2144 "initialize $fp near to $gp location.\n");
2145 fprintf (file
, "\t! If linker fails to use fp-as-gp transformation,\n");
2146 fprintf (file
, "\t! this extra instruction should be "
2147 "eliminated at link stage.\n");
2148 fprintf (file
, "\t.omit_fp_begin\n");
2149 fprintf (file
, "\tla\t$fp,_FP_BASE_\n");
2150 fprintf (file
, "\t! ----------------------------------------\n");
2154 /* Before rtl epilogue has been expanded, this function is used. */
2156 nds32_asm_function_begin_epilogue (FILE *file
)
2158 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2159 we can generate special directive: ".omit_fp_end"
2160 to claim fp-as-gp optimization range.
2161 However, for a naked function,
2162 which means it should not have prologue/epilogue,
2163 using fp-as-gp still requires saving $fp by push/pop behavior and
2164 there is no benefit to use fp-as-gp on such small function.
2165 So we need to make sure this function is NOT naked as well. */
2166 if (!frame_pointer_needed
2167 && !cfun
->machine
->naked_p
2168 && cfun
->machine
->fp_as_gp_p
)
2170 fprintf (file
, "\t! ----------------------------------------\n");
2171 fprintf (file
, "\t! Claim the range of fp-as-gp "
2172 "link time optimization\n");
2173 fprintf (file
, "\t.omit_fp_end\n");
2174 fprintf (file
, "\t! ----------------------------------------\n");
2177 fprintf (file
, "\t! BEGIN EPILOGUE\n");
2180 /* The content produced from this function
2181 will be placed after epilogue body. */
2183 nds32_asm_function_epilogue (FILE *file
)
2185 fprintf (file
, "\t! END EPILOGUE\n");
2189 nds32_asm_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
2190 HOST_WIDE_INT delta
,
2191 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
2196 /* Make sure unwind info is emitted for the thunk if needed. */
2197 final_start_function (emit_barrier (), file
, 1);
2199 this_regno
= (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
)
2205 if (satisfies_constraint_Is15 (GEN_INT (delta
)))
2207 fprintf (file
, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC
"\n",
2208 this_regno
, this_regno
, delta
);
2210 else if (satisfies_constraint_Is20 (GEN_INT (delta
)))
2212 fprintf (file
, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC
"\n", delta
);
2213 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2218 "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC
")\n",
2221 "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC
")\n",
2223 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2227 fprintf (file
, "\tb\t");
2228 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
2229 fprintf (file
, "\n");
2231 final_end_function ();
2234 /* -- Permitting tail calls. */
2236 /* Return true if it is ok to do sibling call optimization. */
2238 nds32_function_ok_for_sibcall (tree decl
,
2239 tree exp ATTRIBUTE_UNUSED
)
2241 /* The DECL is NULL if it is an indirect call. */
2243 /* 1. Do not apply sibling call if -mv3push is enabled,
2244 because pop25 instruction also represents return behavior.
2245 2. If this function is a variadic function, do not apply sibling call
2246 because the stack layout may be a mess.
2247 3. We don't want to apply sibling call optimization for indirect
2248 sibcall because the pop behavior in epilogue may pollute the
2249 content of caller-saved regsiter when the register is used for
2250 indirect sibcall. */
2251 return (!TARGET_V3PUSH
2252 && (cfun
->machine
->va_args_size
== 0)
2256 /* Determine whether we need to enable warning for function return check. */
2258 nds32_warn_func_return (tree decl
)
2260 /* Naked functions are implemented entirely in assembly, including the
2261 return sequence, so suppress warnings about this. */
2262 return !nds32_naked_function_p (decl
);
2266 /* Implementing the Varargs Macros. */
2269 nds32_setup_incoming_varargs (cumulative_args_t ca
,
2272 int *pretend_args_size
,
2273 int second_time ATTRIBUTE_UNUSED
)
2275 unsigned int total_args_regs
;
2276 unsigned int num_of_used_regs
;
2277 unsigned int remaining_reg_count
;
2278 CUMULATIVE_ARGS
*cum
;
2280 /* If we are under hard float abi, we do not need to set *pretend_args_size.
2281 So that all nameless arguments are pushed by caller and all situation
2282 can be handled by GCC itself. */
2283 if (TARGET_HARD_FLOAT
)
2286 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
2287 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
2288 However, for nameless(anonymous) arguments, we should push them on the
2289 stack so that all the nameless arguments appear to have been passed
2290 consecutively in the memory for accessing. Hence, we need to check and
2291 exclude the registers that are used for named arguments. */
2293 cum
= get_cumulative_args (ca
);
2295 /* The MODE and TYPE describe the last argument.
2296 We need those information to determine the remaining registers
2299 = NDS32_MAX_GPR_REGS_FOR_ARGS
+ NDS32_GPR_ARG_FIRST_REGNUM
;
2301 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
2302 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
2304 remaining_reg_count
= total_args_regs
- num_of_used_regs
;
2305 *pretend_args_size
= remaining_reg_count
* UNITS_PER_WORD
;
2311 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
2313 /* If this hook returns true, the named argument of FUNCTION_ARG is always
2314 true for named arguments, and false for unnamed arguments. */
2319 /* Trampolines for Nested Functions. */
2322 nds32_asm_trampoline_template (FILE *f
)
2324 if (TARGET_REDUCED_REGS
)
2326 /* Trampoline is not supported on reduced-set registers yet. */
2327 sorry ("a nested function is not supported for reduced registers");
2331 asm_fprintf (f
, "\t! Trampoline code template\n");
2332 asm_fprintf (f
, "\t! This code fragment will be copied "
2333 "into stack on demand\n");
2335 asm_fprintf (f
, "\tmfusr\t$r16,$pc\n");
2336 asm_fprintf (f
, "\tlwi\t$r15,[$r16 + 20] "
2337 "! load nested function address\n");
2338 asm_fprintf (f
, "\tlwi\t$r16,[$r16 + 16] "
2339 "! load chain_value\n");
2340 asm_fprintf (f
, "\tjr\t$r15\n");
2343 /* Preserve space ($pc + 16) for saving chain_value,
2344 nds32_trampoline_init will fill the value in this slot. */
2345 asm_fprintf (f
, "\t! space for saving chain_value\n");
2346 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2348 /* Preserve space ($pc + 20) for saving nested function address,
2349 nds32_trampoline_init will fill the value in this slot. */
2350 asm_fprintf (f
, "\t! space for saving nested function address\n");
2351 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2354 /* Emit RTL insns to initialize the variable parts of a trampoline. */
2356 nds32_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
2360 /* Nested function address. */
2362 /* The memory rtx that is going to
2363 be filled with chain_value. */
2364 rtx chain_value_mem
;
2365 /* The memory rtx that is going to
2366 be filled with nested function address. */
2367 rtx nested_func_mem
;
2369 /* Start address of trampoline code in stack, for doing cache sync. */
2370 rtx sync_cache_addr
;
2371 /* Temporary register for sync instruction. */
2373 /* Instruction-cache sync instruction,
2374 requesting an argument as starting address. */
2376 /* For convenience reason of doing comparison. */
2377 int tramp_align_in_bytes
;
2379 /* Trampoline is not supported on reduced-set registers yet. */
2380 if (TARGET_REDUCED_REGS
)
2381 sorry ("a nested function is not supported for reduced registers");
2383 /* STEP 1: Copy trampoline code template into stack,
2384 fill up essential data into stack. */
2386 /* Extract nested function address rtx. */
2387 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
2389 /* m_tramp is memory rtx that is going to be filled with trampoline code.
2390 We have nds32_asm_trampoline_template() to emit template pattern. */
2391 emit_block_move (m_tramp
, assemble_trampoline_template (),
2392 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
2394 /* After copying trampoline code into stack,
2395 fill chain_value into stack. */
2396 chain_value_mem
= adjust_address (m_tramp
, SImode
, 16);
2397 emit_move_insn (chain_value_mem
, chain_value
);
2398 /* After copying trampoline code int stack,
2399 fill nested function address into stack. */
2400 nested_func_mem
= adjust_address (m_tramp
, SImode
, 20);
2401 emit_move_insn (nested_func_mem
, fnaddr
);
2403 /* STEP 2: Sync instruction-cache. */
2405 /* We have successfully filled trampoline code into stack.
2406 However, in order to execute code in stack correctly,
2407 we must sync instruction cache. */
2408 sync_cache_addr
= XEXP (m_tramp
, 0);
2409 tmp_reg
= gen_reg_rtx (SImode
);
2410 isync_insn
= gen_unspec_volatile_isync (tmp_reg
);
2412 /* Because nds32_cache_block_size is in bytes,
2413 we get trampoline alignment in bytes for convenient comparison. */
2414 tramp_align_in_bytes
= TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
;
2416 if (tramp_align_in_bytes
>= nds32_cache_block_size
2417 && (tramp_align_in_bytes
% nds32_cache_block_size
) == 0)
2419 /* Under this condition, the starting address of trampoline
2420 must be aligned to the starting address of each cache block
2421 and we do not have to worry about cross-boundary issue. */
2423 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2424 / nds32_cache_block_size
;
2427 emit_move_insn (tmp_reg
,
2428 plus_constant (Pmode
, sync_cache_addr
,
2429 nds32_cache_block_size
* i
));
2430 emit_insn (isync_insn
);
2433 else if (TRAMPOLINE_SIZE
> nds32_cache_block_size
)
2435 /* The starting address of trampoline code
2436 may not be aligned to the cache block,
2437 so the trampoline code may be across two cache block.
2438 We need to sync the last element, which is 4-byte size,
2439 of trampoline template. */
2441 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2442 / nds32_cache_block_size
;
2445 emit_move_insn (tmp_reg
,
2446 plus_constant (Pmode
, sync_cache_addr
,
2447 nds32_cache_block_size
* i
));
2448 emit_insn (isync_insn
);
2451 /* The last element of trampoline template is 4-byte size. */
2452 emit_move_insn (tmp_reg
,
2453 plus_constant (Pmode
, sync_cache_addr
,
2454 TRAMPOLINE_SIZE
- 4));
2455 emit_insn (isync_insn
);
2459 /* This is the simplest case.
2460 Because TRAMPOLINE_SIZE is less than or
2461 equal to nds32_cache_block_size,
2462 we can just sync start address and
2463 the last element of trampoline code. */
2465 /* Sync starting address of tampoline code. */
2466 emit_move_insn (tmp_reg
, sync_cache_addr
);
2467 emit_insn (isync_insn
);
2468 /* Sync the last element, which is 4-byte size,
2469 of trampoline template. */
2470 emit_move_insn (tmp_reg
,
2471 plus_constant (Pmode
, sync_cache_addr
,
2472 TRAMPOLINE_SIZE
- 4));
2473 emit_insn (isync_insn
);
2476 /* Set instruction serialization barrier
2477 to guarantee the correct operations. */
2478 emit_insn (gen_unspec_volatile_isb ());
2482 /* Addressing Modes. */
2485 nds32_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
2487 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
2489 /* When using floating-point instructions,
2490 we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */
2491 if ((mode
== DFmode
|| mode
== SFmode
)
2492 && (GET_CODE (x
) == SYMBOL_REF
2493 || GET_CODE(x
) == CONST
))
2496 /* Allow [post_modify] addressing mode, when using FPU instructions. */
2497 if (GET_CODE (x
) == POST_MODIFY
2500 if (GET_CODE (XEXP (x
, 0)) == REG
2501 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2503 rtx plus_op
= XEXP (x
, 1);
2504 rtx op0
= XEXP (plus_op
, 0);
2505 rtx op1
= XEXP (plus_op
, 1);
2507 if (nds32_address_register_rtx_p (op0
, strict
)
2508 && CONST_INT_P (op1
))
2510 if (satisfies_constraint_Is14 (op1
))
2512 /* If it is not under strictly aligned situation,
2513 we can return true without checking alignment. */
2514 if (!cfun
->machine
->strict_aligned_p
)
2516 /* Make sure address is word alignment.
2517 Currently we do not have 64-bit load/store yet,
2518 so we will use two 32-bit load/store instructions to do
2519 memory access and they are single word alignment. */
2520 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1
)))
2528 /* For (mem:DI addr) or (mem:DF addr) case,
2529 we only allow 'addr' to be [reg], [symbol_ref],
2530 [const], or [reg + const_int] pattern. */
2531 if (mode
== DImode
|| mode
== DFmode
)
2533 /* Allow [Reg + const_int] addressing mode. */
2534 if (GET_CODE (x
) == PLUS
)
2536 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2537 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
)
2538 && CONST_INT_P (XEXP (x
, 1)))
2540 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2541 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
)
2542 && CONST_INT_P (XEXP (x
, 0)))
2546 /* Allow [post_inc] and [post_dec] addressing mode. */
2547 if (GET_CODE (x
) == POST_INC
|| GET_CODE (x
) == POST_DEC
)
2549 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2553 /* Now check [reg], [symbol_ref], and [const]. */
2554 if (GET_CODE (x
) != REG
2555 && GET_CODE (x
) != SYMBOL_REF
2556 && GET_CODE (x
) != CONST
)
2560 /* Check if 'x' is a valid address. */
2561 switch (GET_CODE (x
))
2564 /* (mem (reg A)) => [Ra] */
2565 return nds32_address_register_rtx_p (x
, strict
);
2568 /* (mem (symbol_ref A)) => [symbol_ref] */
2569 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
2570 during or after LRA/reload phase. */
2571 if (TARGET_CMODEL_LARGE
2572 && (reload_completed
2573 || reload_in_progress
2574 || lra_in_progress
))
2576 /* If -mcmodel=medium and the symbol references to rodata section,
2577 the 'symbol_ref' is not a valid address during or after
2578 LRA/reload phase. */
2579 if (TARGET_CMODEL_MEDIUM
2580 && NDS32_SYMBOL_REF_RODATA_P (x
)
2581 && (reload_completed
2582 || reload_in_progress
2583 || lra_in_progress
))
2589 /* (mem (const (...)))
2590 => [ + const_addr ], where const_addr = symbol_ref + const_int */
2591 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
2593 rtx plus_op
= XEXP (x
, 0);
2595 rtx op0
= XEXP (plus_op
, 0);
2596 rtx op1
= XEXP (plus_op
, 1);
2598 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2600 /* Now we see the [ + const_addr ] pattern, but we need
2601 some further checking. */
2602 /* If -mcmodel=large, the 'const_addr' is not a valid address
2603 during or after LRA/reload phase. */
2604 if (TARGET_CMODEL_LARGE
2605 && (reload_completed
2606 || reload_in_progress
2607 || lra_in_progress
))
2609 /* If -mcmodel=medium and the symbol references to rodata section,
2610 the 'const_addr' is not a valid address during or after
2611 LRA/reload phase. */
2612 if (TARGET_CMODEL_MEDIUM
2613 && NDS32_SYMBOL_REF_RODATA_P (op0
)
2614 && (reload_completed
2615 || reload_in_progress
2616 || lra_in_progress
))
2619 /* At this point we can make sure 'const_addr' is a
2628 /* (mem (post_modify (reg) (plus (reg) (reg))))
2630 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2631 => [Ra], const_int */
2632 if (GET_CODE (XEXP (x
, 0)) == REG
2633 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2635 rtx plus_op
= XEXP (x
, 1);
2637 rtx op0
= XEXP (plus_op
, 0);
2638 rtx op1
= XEXP (plus_op
, 1);
2640 if (nds32_address_register_rtx_p (op0
, strict
)
2641 && nds32_legitimate_index_p (mode
, op1
, strict
))
2651 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2652 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2653 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2654 We only need to deal with register Ra. */
2655 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2661 /* (mem (plus reg const_int))
2663 /* (mem (plus reg reg))
2665 /* (mem (plus (mult reg const_int) reg))
2666 => [Ra + Rb << sv] */
2667 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2668 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
))
2670 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2671 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
))
2677 /* (mem (lo_sum (reg) (symbol_ref))) */
2678 /* (mem (lo_sum (reg) (const))) */
2679 gcc_assert (REG_P (XEXP (x
, 0)));
2680 if (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
2681 || GET_CODE (XEXP (x
, 1)) == CONST
)
2682 return nds32_legitimate_address_p (mode
, XEXP (x
, 1), strict
);
2692 /* Condition Code Status. */
2694 /* -- Representation of condition codes using registers. */
2697 nds32_canonicalize_comparison (int *code
,
2698 rtx
*op0 ATTRIBUTE_UNUSED
,
2700 bool op0_preserve_value ATTRIBUTE_UNUSED
)
2702 /* When the instruction combination pass tries to combine a comparison insn
2703 with its previous insns, it also transforms the operator in order to
2704 minimize its constant field. For example, it tries to transform a
2705 comparison insn from
2708 (const_int 10 [0xa])))
2712 (const_int 9 [0x9])))
2714 However, the nds32 target only provides instructions supporting the LTU
2715 operation directly, and the implementation of the pattern "cbranchsi4"
2716 only expands the LTU form. In order to handle the non-LTU operations
2717 generated from passes other than the RTL expansion pass, we have to
2718 implement this hook to revert those changes. Since we only expand the LTU
2719 operator in the RTL expansion pass, we might only need to handle the LEU
2720 case, unless we find other optimization passes perform more aggressive
2723 if (*code
== LEU
&& CONST_INT_P (*op1
))
2725 *op1
= gen_int_mode (INTVAL (*op1
) + 1, SImode
);
2731 /* Describing Relative Costs of Operations. */
2734 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2738 if ((from
== FP_REGS
&& to
!= FP_REGS
)
2739 || (from
!= FP_REGS
&& to
== FP_REGS
))
2741 else if (from
== HIGH_REGS
|| to
== HIGH_REGS
)
2742 return optimize_size
? 6 : 2;
2748 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2749 reg_class_t rclass ATTRIBUTE_UNUSED
,
2750 bool in ATTRIBUTE_UNUSED
)
2755 /* This target hook describes the relative costs of RTL expressions.
2756 Return 'true' when all subexpressions of x have been processed.
2757 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2758 Refer to gcc/rtlanal.c for more information. */
2760 nds32_rtx_costs (rtx x
,
2767 return nds32_rtx_costs_impl (x
, mode
, outer_code
, opno
, total
, speed
);
2771 nds32_address_cost (rtx address
,
2776 return nds32_address_cost_impl (address
, mode
, as
, speed
);
2780 /* Dividing the Output into Sections (Texts, Data, . . . ). */
2782 /* If references to a symbol or a constant must be treated differently
2783 depending on something about the variable or function named by the symbol
2784 (such as what section it is in), we use this hook to store flags
2785 in symbol_ref rtx. */
2787 nds32_encode_section_info (tree decl
, rtx rtl
, int new_decl_p
)
2789 default_encode_section_info (decl
, rtl
, new_decl_p
);
2791 /* For the memory rtx, if it references to rodata section, we can store
2792 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
2793 nds32_legitimate_address_p() can determine how to treat such symbol_ref
2794 based on -mcmodel=X and this information. */
2795 if (MEM_P (rtl
) && MEM_READONLY_P (rtl
))
2797 rtx addr
= XEXP (rtl
, 0);
2799 if (GET_CODE (addr
) == SYMBOL_REF
)
2801 /* For (mem (symbol_ref X)) case. */
2802 SYMBOL_REF_FLAGS (addr
) |= NDS32_SYMBOL_FLAG_RODATA
;
2804 else if (GET_CODE (addr
) == CONST
2805 && GET_CODE (XEXP (addr
, 0)) == PLUS
)
2807 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
2808 rtx plus_op
= XEXP (addr
, 0);
2809 rtx op0
= XEXP (plus_op
, 0);
2810 rtx op1
= XEXP (plus_op
, 1);
2812 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2813 SYMBOL_REF_FLAGS (op0
) |= NDS32_SYMBOL_FLAG_RODATA
;
2819 /* Defining the Output Assembler Language. */
2821 /* -- The Overall Framework of an Assembler File. */
2824 nds32_asm_file_start (void)
2826 default_file_start ();
2828 /* Tell assembler which ABI we are using. */
2829 fprintf (asm_out_file
, "\t! ABI version\n");
2830 if (TARGET_HARD_FLOAT
)
2831 fprintf (asm_out_file
, "\t.abi_2fp_plus\n");
2833 fprintf (asm_out_file
, "\t.abi_2\n");
2835 /* Tell assembler that this asm code is generated by compiler. */
2836 fprintf (asm_out_file
, "\t! This asm file is generated by compiler\n");
2837 fprintf (asm_out_file
, "\t.flag\tverbatim\n");
2838 /* Give assembler the size of each vector for interrupt handler. */
2839 fprintf (asm_out_file
, "\t! This vector size directive is required "
2840 "for checking inconsistency on interrupt handler\n");
2841 fprintf (asm_out_file
, "\t.vec_size\t%d\n", nds32_isr_vector_size
);
2843 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2846 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V2");
2848 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3");
2850 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3M");
2852 if (TARGET_CMODEL_SMALL
)
2853 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "SMALL");
2854 if (TARGET_CMODEL_MEDIUM
)
2855 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "MEDIUM");
2856 if (TARGET_CMODEL_LARGE
)
2857 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "LARGE");
2859 fprintf (asm_out_file
, "\t! Endian setting\t: %s\n",
2860 ((TARGET_BIG_ENDIAN
) ? "big-endian"
2861 : "little-endian"));
2862 fprintf (asm_out_file
, "\t! Use SP floating-point instruction\t: %s\n",
2863 ((TARGET_FPU_SINGLE
) ? "Yes"
2865 fprintf (asm_out_file
, "\t! Use DP floating-point instruction\t: %s\n",
2866 ((TARGET_FPU_DOUBLE
) ? "Yes"
2868 fprintf (asm_out_file
, "\t! ABI version\t\t: %s\n",
2869 ((TARGET_HARD_FLOAT
) ? "ABI2FP+"
2872 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2874 fprintf (asm_out_file
, "\t! Use conditional move\t\t: %s\n",
2875 ((TARGET_CMOV
) ? "Yes"
2877 fprintf (asm_out_file
, "\t! Use performance extension\t: %s\n",
2878 ((TARGET_EXT_PERF
) ? "Yes"
2880 fprintf (asm_out_file
, "\t! Use performance extension 2\t: %s\n",
2881 ((TARGET_EXT_PERF2
) ? "Yes"
2883 fprintf (asm_out_file
, "\t! Use string extension\t\t: %s\n",
2884 ((TARGET_EXT_STRING
) ? "Yes"
2887 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2889 fprintf (asm_out_file
, "\t! V3PUSH instructions\t: %s\n",
2890 ((TARGET_V3PUSH
) ? "Yes"
2892 fprintf (asm_out_file
, "\t! 16-bit instructions\t: %s\n",
2893 ((TARGET_16_BIT
) ? "Yes"
2895 fprintf (asm_out_file
, "\t! Reduced registers set\t: %s\n",
2896 ((TARGET_REDUCED_REGS
) ? "Yes"
2899 fprintf (asm_out_file
, "\t! Support unaligned access\t\t: %s\n",
2900 (flag_unaligned_access
? "Yes"
2903 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2906 fprintf (asm_out_file
, "\t! Optimization level\t: -Os\n");
2907 else if (optimize_fast
)
2908 fprintf (asm_out_file
, "\t! Optimization level\t: -Ofast\n");
2909 else if (optimize_debug
)
2910 fprintf (asm_out_file
, "\t! Optimization level\t: -Og\n");
2912 fprintf (asm_out_file
, "\t! Optimization level\t: -O%d\n", optimize
);
2914 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2916 fprintf (asm_out_file
, "\t! Cache block size\t: %d\n",
2917 nds32_cache_block_size
);
2919 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2921 nds32_asm_file_start_for_isr ();
2925 nds32_asm_file_end (void)
2927 nds32_asm_file_end_for_isr ();
2929 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2932 /* -- Output and Generation of Labels. */
2935 nds32_asm_globalize_label (FILE *stream
, const char *name
)
2937 fputs ("\t.global\t", stream
);
2938 assemble_name (stream
, name
);
2939 fputs ("\n", stream
);
2942 /* -- Output of Assembler Instructions. */
2945 nds32_print_operand (FILE *stream
, rtx x
, int code
)
2947 HOST_WIDE_INT op_value
= 0;
2948 HOST_WIDE_INT one_position
;
2949 HOST_WIDE_INT zero_position
;
2950 bool pick_lsb_p
= false;
2951 bool pick_msb_p
= false;
2954 if (CONST_INT_P (x
))
2955 op_value
= INTVAL (x
);
2960 /* Do nothing special. */
2964 /* Use exact_log2() to search the 0-bit position. */
2965 gcc_assert (CONST_INT_P (x
));
2966 zero_position
= exact_log2 (~UINTVAL (x
) & GET_MODE_MASK (SImode
));
2967 gcc_assert (zero_position
!= -1);
2968 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, zero_position
);
2970 /* No need to handle following process, so return immediately. */
2974 gcc_assert (MEM_P (x
)
2975 && GET_CODE (XEXP (x
, 0)) == PLUS
2976 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
2977 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (XEXP (XEXP (x
, 0), 1)));
2979 /* No need to handle following process, so return immediately. */
2982 /* Use exact_log2() to search the 1-bit position. */
2983 gcc_assert (CONST_INT_P (x
));
2984 one_position
= exact_log2 (UINTVAL (x
) & GET_MODE_MASK (SImode
));
2985 gcc_assert (one_position
!= -1);
2986 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, one_position
);
2988 /* No need to handle following process, so return immediately. */
2992 /* X is supposed to be REG rtx. */
2993 gcc_assert (REG_P (x
));
2994 /* Claim that we are going to pick LSB part of X. */
2999 /* X is supposed to be REG rtx. */
3000 gcc_assert (REG_P (x
));
3001 /* Claim that we are going to pick MSB part of X. */
3006 /* 'x' is supposed to be CONST_INT, get the value. */
3007 gcc_assert (CONST_INT_P (x
));
3009 /* According to the Andes architecture,
3010 the system/user register index range is 0 ~ 1023.
3011 In order to avoid conflict between user-specified-integer value
3012 and enum-specified-register value,
3013 the 'enum nds32_intrinsic_registers' value
3014 in nds32_intrinsic.h starts from 1024. */
3015 if (op_value
< 1024 && op_value
>= 0)
3017 /* If user gives integer value directly (0~1023),
3018 we just print out the value. */
3019 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, op_value
);
3021 else if (op_value
< 0
3022 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
3025 /* The enum index value for array size is out of range. */
3026 error ("intrinsic register index is out of range");
3030 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3031 we can print out register name. Remember to substract 1024. */
3032 fprintf (stream
, "%s",
3033 nds32_intrinsic_register_names
[op_value
- 1024]);
3036 /* No need to handle following process, so return immediately. */
3039 case 'R': /* cctl valck */
3040 /* Note the cctl divide to 5 group and share the same name table. */
3041 if (op_value
< 0 || op_value
> 4)
3042 error ("CCTL intrinsic function subtype out of range!");
3043 fprintf (stream
, "%s", nds32_cctl_names
[op_value
]);
3046 case 'T': /* cctl idxwbinv */
3047 /* Note the cctl divide to 5 group and share the same name table. */
3048 if (op_value
< 0 || op_value
> 4)
3049 error ("CCTL intrinsic function subtype out of range!");
3050 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 4]);
3053 case 'U': /* cctl vawbinv */
3054 /* Note the cctl divide to 5 group and share the same name table. */
3055 if (op_value
< 0 || op_value
> 4)
3056 error ("CCTL intrinsic function subtype out of range!");
3057 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 8]);
3060 case 'X': /* cctl idxread */
3061 /* Note the cctl divide to 5 group and share the same name table. */
3062 if (op_value
< 0 || op_value
> 4)
3063 error ("CCTL intrinsic function subtype out of range!");
3064 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 12]);
3067 case 'W': /* cctl idxwitre */
3068 /* Note the cctl divide to 5 group and share the same name table. */
3069 if (op_value
< 0 || op_value
> 4)
3070 error ("CCTL intrinsic function subtype out of range!");
3071 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 16]);
3074 case 'Z': /* dpref */
3075 fprintf (stream
, "%s", nds32_dpref_names
[op_value
]);
3080 output_operand_lossage ("invalid operand output code");
3084 switch (GET_CODE (x
))
3088 output_addr_const (stream
, x
);
3092 /* Print a Double-precision register name. */
3093 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3094 && NDS32_IS_FPR_REGNUM (REGNO (x
)))
3097 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
))
3099 output_operand_lossage ("invalid operand for code '%c'", code
);
3102 fprintf (stream
, "$fd%d", (regno
- NDS32_FIRST_FPR_REGNUM
) >> 1);
3106 /* Print LSB or MSB part of register pair if the
3107 constraint modifier 'L' or 'H' is specified. */
3108 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3109 && NDS32_IS_GPR_REGNUM (REGNO (x
)))
3111 if ((pick_lsb_p
&& WORDS_BIG_ENDIAN
)
3112 || (pick_msb_p
&& !WORDS_BIG_ENDIAN
))
3114 /* If we would like to print out LSB register under big-endian,
3115 or print out MSB register under little-endian, we need to
3116 increase register number. */
3119 fputs (reg_names
[regno
], stream
);
3124 /* Forbid using static chain register ($r16)
3125 on reduced-set registers configuration. */
3126 if (TARGET_REDUCED_REGS
3127 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3128 sorry ("a nested function is not supported for reduced registers");
3130 /* Normal cases, print out register name. */
3131 fputs (reg_names
[REGNO (x
)], stream
);
3135 output_address (GET_MODE (x
), XEXP (x
, 0));
3139 if (GET_CODE (XEXP (x
, 0)) == CONST_DOUBLE
)
3141 const REAL_VALUE_TYPE
*rv
;
3143 gcc_assert (GET_MODE (x
) == SFmode
);
3145 rv
= CONST_DOUBLE_REAL_VALUE (XEXP (x
, 0));
3146 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3148 fprintf (stream
, "hi20(0x%lx)", val
);
3155 const REAL_VALUE_TYPE
*rv
;
3157 gcc_assert (GET_MODE (x
) == SFmode
);
3159 rv
= CONST_DOUBLE_REAL_VALUE (x
);
3160 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3162 fprintf (stream
, "0x%lx", val
);
3168 output_addr_const (stream
, x
);
3172 /* Generally, output_addr_const () is able to handle most cases.
3173 We want to see what CODE could appear,
3174 so we use gcc_unreachable() to stop it. */
3182 nds32_print_operand_address (FILE *stream
, machine_mode
/*mode*/, rtx x
)
3186 switch (GET_CODE (x
))
3190 /* [ + symbol_ref] */
3191 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3192 fputs ("[ + ", stream
);
3193 output_addr_const (stream
, x
);
3194 fputs ("]", stream
);
3198 /* Forbid using static chain register ($r16)
3199 on reduced-set registers configuration. */
3200 if (TARGET_REDUCED_REGS
3201 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3202 sorry ("a nested function is not supported for reduced registers");
3205 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
3212 /* Checking op0, forbid using static chain register ($r16)
3213 on reduced-set registers configuration. */
3214 if (TARGET_REDUCED_REGS
3216 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3217 sorry ("a nested function is not supported for reduced registers");
3218 /* Checking op1, forbid using static chain register ($r16)
3219 on reduced-set registers configuration. */
3220 if (TARGET_REDUCED_REGS
3222 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3223 sorry ("a nested function is not supported for reduced registers");
3225 if (REG_P (op0
) && CONST_INT_P (op1
))
3228 fprintf (stream
, "[%s + (" HOST_WIDE_INT_PRINT_DEC
")]",
3229 reg_names
[REGNO (op0
)], INTVAL (op1
));
3231 else if (REG_P (op0
) && REG_P (op1
))
3234 fprintf (stream
, "[%s + %s]",
3235 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3237 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
3240 From observation, the pattern looks like:
3241 (plus:SI (mult:SI (reg:SI 58)
3242 (const_int 4 [0x4]))
3246 /* We need to set sv to output shift value. */
3247 if (INTVAL (XEXP (op0
, 1)) == 1)
3249 else if (INTVAL (XEXP (op0
, 1)) == 2)
3251 else if (INTVAL (XEXP (op0
, 1)) == 4)
3253 else if (INTVAL (XEXP (op0
, 1)) == 8)
3258 fprintf (stream
, "[%s + %s << %d]",
3259 reg_names
[REGNO (op1
)],
3260 reg_names
[REGNO (XEXP (op0
, 0))],
3265 /* The control flow is not supposed to be here. */
3273 /* (post_modify (regA) (plus (regA) (regB)))
3274 (post_modify (regA) (plus (regA) (const_int)))
3275 We would like to extract
3276 regA and regB (or const_int) from plus rtx. */
3277 op0
= XEXP (XEXP (x
, 1), 0);
3278 op1
= XEXP (XEXP (x
, 1), 1);
3280 /* Checking op0, forbid using static chain register ($r16)
3281 on reduced-set registers configuration. */
3282 if (TARGET_REDUCED_REGS
3284 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3285 sorry ("a nested function is not supported for reduced registers");
3286 /* Checking op1, forbid using static chain register ($r16)
3287 on reduced-set registers configuration. */
3288 if (TARGET_REDUCED_REGS
3290 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3291 sorry ("a nested function is not supported for reduced registers");
3293 if (REG_P (op0
) && REG_P (op1
))
3296 fprintf (stream
, "[%s], %s",
3297 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3299 else if (REG_P (op0
) && CONST_INT_P (op1
))
3302 fprintf (stream
, "[%s], " HOST_WIDE_INT_PRINT_DEC
,
3303 reg_names
[REGNO (op0
)], INTVAL (op1
));
3307 /* The control flow is not supposed to be here. */
3318 /* Checking op0, forbid using static chain register ($r16)
3319 on reduced-set registers configuration. */
3320 if (TARGET_REDUCED_REGS
3322 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3323 sorry ("a nested function is not supported for reduced registers");
3327 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3328 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3329 We only need to deal with register Ra. */
3330 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
3334 /* The control flow is not supposed to be here. */
3342 /* Generally, output_addr_const () is able to handle most cases.
3343 We want to see what CODE could appear,
3344 so we use gcc_unreachable() to stop it. */
3351 /* -- Assembler Commands for Exception Regions. */
3354 nds32_dwarf_register_span (rtx reg
)
3356 rtx dwarf_high
, dwarf_low
;
3361 mode
= GET_MODE (reg
);
3362 regno
= REGNO (reg
);
3364 /* We need to adjust dwarf register information for floating-point registers
3365 rather than using default register number mapping. */
3366 if (regno
>= NDS32_FIRST_FPR_REGNUM
3367 && regno
<= NDS32_LAST_FPR_REGNUM
)
3369 if (mode
== DFmode
|| mode
== SCmode
)
3371 /* By default, GCC maps increasing register numbers to increasing
3372 memory locations, but paired FPRs in NDS32 target are always
3378 We must return parallel rtx to represent such layout. */
3379 dwarf_high
= gen_rtx_REG (word_mode
, regno
);
3380 dwarf_low
= gen_rtx_REG (word_mode
, regno
+ 1);
3381 return gen_rtx_PARALLEL (VOIDmode
,
3382 gen_rtvec (2, dwarf_low
, dwarf_high
));
3384 else if (mode
== DCmode
)
3386 rtx dwarf_high_re
= gen_rtx_REG (word_mode
, regno
);
3387 rtx dwarf_low_re
= gen_rtx_REG (word_mode
, regno
+ 1);
3388 rtx dwarf_high_im
= gen_rtx_REG (word_mode
, regno
);
3389 rtx dwarf_low_im
= gen_rtx_REG (word_mode
, regno
+ 1);
3390 return gen_rtx_PARALLEL (VOIDmode
,
3391 gen_rtvec (4, dwarf_low_re
, dwarf_high_re
,
3392 dwarf_high_im
, dwarf_low_im
));
3394 else if (mode
== SFmode
|| mode
== SImode
)
3396 /* Create new dwarf information with adjusted register number. */
3397 dwarf_single
= gen_rtx_REG (word_mode
, regno
);
3398 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, dwarf_single
));
3402 /* We should not be here. */
3410 /* Map internal gcc register numbers to DWARF2 register numbers. */
3413 nds32_dbx_register_number (unsigned int regno
)
3415 /* The nds32 port in GDB maintains a mapping between dwarf register
3416 number and displayed register name. For backward compatibility to
3417 previous toolchain, currently our gdb still has four registers
3418 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3419 does not count those four registers in its register number table.
3420 So we have to add 4 on its register number and then create new
3421 dwarf information. Hopefully we can discard such workaround
3423 if (NDS32_IS_FPR_REGNUM (regno
))
3430 /* Defining target-specific uses of __attribute__. */
3432 /* Add some checking after merging attributes. */
3434 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
3436 tree combined_attrs
;
3438 /* Create combined attributes. */
3439 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
3440 DECL_ATTRIBUTES (newdecl
));
3442 /* Since newdecl is acutally a duplicate of olddecl,
3443 we can take olddecl for some operations. */
3444 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
3446 /* Check isr-specific attributes conflict. */
3447 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
3450 return combined_attrs
;
3453 /* Add some checking when inserting attributes. */
3455 nds32_insert_attributes (tree decl
, tree
*attributes
)
3457 /* For function declaration, we need to check isr-specific attributes:
3458 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3459 2. Check valid integer value for interrupt/exception.
3460 3. Check valid integer value for reset.
3461 4. Check valid function for nmi/warm. */
3462 if (TREE_CODE (decl
) == FUNCTION_DECL
)
3465 tree intr
, excp
, reset
;
3467 /* Pick up function attributes. */
3468 func_attrs
= *attributes
;
3470 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3471 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
3473 /* Now we are starting to check valid id value
3474 for interrupt/exception/reset.
3475 Note that we ONLY check its validity here.
3476 To construct isr vector information, it is still performed
3477 by nds32_construct_isr_vectors_information(). */
3478 intr
= lookup_attribute ("interrupt", func_attrs
);
3479 excp
= lookup_attribute ("exception", func_attrs
);
3480 reset
= lookup_attribute ("reset", func_attrs
);
3484 /* Deal with interrupt/exception. */
3486 unsigned int lower_bound
, upper_bound
;
3488 /* The way to handle interrupt or exception is the same,
3489 we just need to take care of actual vector number.
3490 For interrupt(0..63), the actual vector number is (9..72).
3491 For exception(1..8), the actual vector number is (1..8). */
3492 lower_bound
= (intr
) ? (0) : (1);
3493 upper_bound
= (intr
) ? (63) : (8);
3495 /* Prepare id list so that we can traverse id value. */
3496 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
3498 /* 2. Check valid integer value for interrupt/exception. */
3503 /* Pick up each vector id value. */
3504 id
= TREE_VALUE (id_list
);
3505 /* Issue error if it is not a valid integer value. */
3506 if (TREE_CODE (id
) != INTEGER_CST
3507 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3508 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3509 error ("invalid id value for interrupt/exception attribute");
3511 /* Advance to next id. */
3512 id_list
= TREE_CHAIN (id_list
);
3517 /* Deal with reset. */
3521 unsigned int lower_bound
;
3522 unsigned int upper_bound
;
3524 /* Prepare id_list and identify id value so that
3525 we can check if total number of vectors is valid. */
3526 id_list
= TREE_VALUE (reset
);
3527 id
= TREE_VALUE (id_list
);
3529 /* The maximum numbers for user's interrupt is 64. */
3533 /* 3. Check valid integer value for reset. */
3534 if (TREE_CODE (id
) != INTEGER_CST
3535 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3536 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3537 error ("invalid id value for reset attribute");
3539 /* 4. Check valid function for nmi/warm. */
3540 nmi
= lookup_attribute ("nmi", func_attrs
);
3541 warm
= lookup_attribute ("warm", func_attrs
);
3543 if (nmi
!= NULL_TREE
)
3548 nmi_func_list
= TREE_VALUE (nmi
);
3549 nmi_func
= TREE_VALUE (nmi_func_list
);
3551 /* Issue error if it is not a valid nmi function. */
3552 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
3553 error ("invalid nmi function for reset attribute");
3556 if (warm
!= NULL_TREE
)
3558 tree warm_func_list
;
3561 warm_func_list
= TREE_VALUE (warm
);
3562 warm_func
= TREE_VALUE (warm_func_list
);
3564 /* Issue error if it is not a valid warm function. */
3565 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
3566 error ("invalid warm function for reset attribute");
3571 /* No interrupt, exception, or reset attribute is set. */
3578 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
3579 tree pop_target ATTRIBUTE_UNUSED
)
3581 /* Currently, we do not parse any pragma target by ourself,
3582 so just simply return false. */
3587 nds32_option_override (void)
3589 /* After all the command options have been parsed,
3590 we shall deal with some flags for changing compiler settings. */
3592 /* At first, we check if we have to strictly
3593 set some flags based on ISA family. */
3596 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
3597 target_flags
&= ~MASK_V3PUSH
;
3601 /* Under V3 ISA, currently nothing should be strictly set. */
3605 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
3606 target_flags
|= MASK_REDUCED_REGS
;
3607 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
3608 target_flags
&= ~MASK_EXT_PERF
;
3609 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
3610 target_flags
&= ~MASK_EXT_PERF2
;
3611 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
3612 target_flags
&= ~MASK_EXT_STRING
;
3615 /* See if we are using reduced-set registers:
3616 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
3617 If so, we must forbid using $r11~$r14, $r16~$r27. */
3618 if (TARGET_REDUCED_REGS
)
3622 /* Prevent register allocator from
3623 choosing it as doing register allocation. */
3624 for (r
= 11; r
<= 14; r
++)
3625 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3626 for (r
= 16; r
<= 27; r
++)
3627 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3632 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
3633 target_flags
&= ~MASK_V3PUSH
;
3636 if (TARGET_HARD_FLOAT
&& !(TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
3638 if (nds32_arch_option
== ARCH_V3S
|| nds32_arch_option
== ARCH_V3F
)
3639 error ("Disable FPU ISA, "
3640 "the ABI option must be enable '-mfloat-abi=soft'");
3642 error ("'-mabi=2fp+' option only support when FPU available, "
3643 "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
3646 /* Currently, we don't support PIC code generation yet. */
3648 sorry ("position-independent code not supported");
3650 nds32_register_passes ();
3654 /* Miscellaneous Parameters. */
3657 nds32_md_asm_adjust (vec
<rtx
> &outputs ATTRIBUTE_UNUSED
,
3658 vec
<rtx
> &inputs ATTRIBUTE_UNUSED
,
3659 vec
<const char *> &constraints ATTRIBUTE_UNUSED
,
3660 vec
<rtx
> &clobbers
, HARD_REG_SET
&clobbered_regs
)
3662 clobbers
.safe_push (gen_rtx_REG (SImode
, TA_REGNUM
));
3663 SET_HARD_REG_BIT (clobbered_regs
, TA_REGNUM
);
3668 nds32_init_builtins (void)
3670 nds32_init_builtins_impl ();
3674 nds32_builtin_decl (unsigned code
, bool initialize_p
)
3676 /* Implement in nds32-intrinsic.c. */
3677 return nds32_builtin_decl_impl (code
, initialize_p
);
3681 nds32_expand_builtin (tree exp
,
3687 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
3691 /* ------------------------------------------------------------------------ */
3693 /* PART 4: Implemet extern function definitions,
3694 the prototype is in nds32-protos.h. */
3696 /* Run-time Target Specification. */
3699 nds32_cpu_cpp_builtins(struct cpp_reader
*pfile
)
3701 #define builtin_define(TXT) cpp_define (pfile, TXT)
3702 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
3703 builtin_define ("__nds32__");
3704 builtin_define ("__NDS32__");
3706 if (TARGET_HARD_FLOAT
)
3707 builtin_define ("__NDS32_ABI_2FP_PLUS__");
3709 builtin_define ("__NDS32_ABI_2__");
3712 builtin_define ("__NDS32_ISA_V2__");
3714 builtin_define ("__NDS32_ISA_V3__");
3716 builtin_define ("__NDS32_ISA_V3M__");
3718 if (TARGET_FPU_SINGLE
)
3719 builtin_define ("__NDS32_EXT_FPU_SP__");
3720 if (TARGET_FPU_DOUBLE
)
3721 builtin_define ("__NDS32_EXT_FPU_DP__");
3723 if (TARGET_EXT_FPU_FMA
)
3724 builtin_define ("__NDS32_EXT_FPU_FMA__");
3725 if (NDS32_EXT_FPU_DOT_E
)
3726 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
3727 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
3729 switch (nds32_fp_regnum
)
3733 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
3737 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
3741 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
3745 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
3752 if (TARGET_BIG_ENDIAN
)
3753 builtin_define ("__NDS32_EB__");
3755 builtin_define ("__NDS32_EL__");
3757 if (TARGET_REDUCED_REGS
)
3758 builtin_define ("__NDS32_REDUCED_REGS__");
3760 builtin_define ("__NDS32_CMOV__");
3761 if (TARGET_EXT_PERF
)
3762 builtin_define ("__NDS32_EXT_PERF__");
3763 if (TARGET_EXT_PERF2
)
3764 builtin_define ("__NDS32_EXT_PERF2__");
3765 if (TARGET_EXT_STRING
)
3766 builtin_define ("__NDS32_EXT_STRING__");
3768 builtin_define ("__NDS32_16_BIT__");
3769 if (TARGET_GP_DIRECT
)
3770 builtin_define ("__NDS32_GP_DIRECT__");
3772 builtin_define ("__NDS32_VH__");
3774 if (TARGET_BIG_ENDIAN
)
3775 builtin_define ("__big_endian__");
3777 builtin_assert ("cpu=nds32");
3778 builtin_assert ("machine=nds32");
3780 if (TARGET_HARD_FLOAT
)
3781 builtin_define ("__NDS32_ABI_2FP_PLUS");
3783 builtin_define ("__NDS32_ABI_2");
3785 #undef builtin_define
3786 #undef builtin_assert
3790 /* Defining Data Structures for Per-function Information. */
3793 nds32_init_expanders (void)
3795 /* Arrange to initialize and mark the machine per-function status. */
3796 init_machine_status
= nds32_init_machine_status
;
3800 /* Register Usage. */
3802 /* -- Order of Allocation of Registers. */
3805 nds32_adjust_reg_alloc_order (void)
3807 const int nds32_reg_alloc_order
[] = REG_ALLOC_ORDER
;
3809 /* Copy the default register allocation order, which is designed
3810 to optimize for code size. */
3811 memcpy(reg_alloc_order
, nds32_reg_alloc_order
, sizeof (reg_alloc_order
));
3813 /* Adjust few register allocation order when optimizing for speed. */
3816 memcpy (reg_alloc_order
, nds32_reg_alloc_order_for_speed
,
3817 sizeof (nds32_reg_alloc_order_for_speed
));
3821 /* -- How Values Fit in Registers. */
3824 nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED
,
3827 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
3830 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3833 nds32_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
3835 if (regno
> FIRST_PSEUDO_REGISTER
)
3838 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
) && NDS32_IS_FPR_REGNUM (regno
))
3840 if (NDS32_IS_EXT_FPR_REGNUM(regno
))
3841 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno
) && (mode
== DFmode
));
3842 else if (mode
== SFmode
|| mode
== SImode
)
3843 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno
);
3844 else if (mode
== DFmode
)
3845 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
);
3850 /* Restrict double-word quantities to even register pairs. */
3851 if (regno
<= NDS32_LAST_GPR_REGNUM
)
3852 return (targetm
.hard_regno_nregs (regno
, mode
) == 1
3858 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
3859 tie QI/HI/SI modes together. */
3862 nds32_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3864 if ((GET_MODE_CLASS (mode1
) == MODE_INT
3865 && GET_MODE_CLASS (mode2
) == MODE_INT
)
3866 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
3867 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
)
3870 if (GET_MODE_SIZE (mode1
) == GET_MODE_SIZE (mode2
))
3872 if ((TARGET_FPU_SINGLE
&& !TARGET_FPU_DOUBLE
)
3873 && (mode1
== DFmode
|| mode2
== DFmode
))
3882 /* Register Classes. */
3885 nds32_regno_reg_class (int regno
)
3887 /* Refer to nds32.h for more register class details. */
3889 if (regno
>= 0 && regno
<= 7)
3891 else if (regno
>= 8 && regno
<= 11)
3893 else if (regno
>= 12 && regno
<= 14)
3895 else if (regno
== 15)
3897 else if (regno
>= 16 && regno
<= 19)
3899 else if (regno
>= 20 && regno
<= 31)
3901 else if (regno
== 32 || regno
== 33)
3903 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
3904 know how to allocate register for $SFP and $AP, just tell IRA they
3905 are GENERAL_REGS, and ARM do this hack too. */
3906 return GENERAL_REGS
;
3908 else if (regno
>= 34 && regno
<= 97)
3915 /* Stack Layout and Calling Conventions. */
3917 /* -- Basic Stack Layout. */
3920 nds32_dynamic_chain_address (rtx frameaddr
)
3924 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
3925 We can access dynamic chain address from stack by [$fp - 12]. */
3926 return plus_constant (Pmode
, frameaddr
, -12);
3930 /* For general case we push $fp and $lp into stack at prologue.
3931 We can access dynamic chain address from stack by [$fp - 8]. */
3932 return plus_constant (Pmode
, frameaddr
, -8);
3937 nds32_return_addr_rtx (int count
,
3945 /* In nds32 ABI design, we can expect that $lp is always available
3946 from stack by [$fp - 4] location. */
3948 addr
= plus_constant (Pmode
, frameaddr
, offset
);
3949 addr
= memory_address (Pmode
, addr
);
3951 return gen_rtx_MEM (Pmode
, addr
);
3954 /* If count == 0, it means we are at current frame,
3955 the return address is $r30 ($lp). */
3956 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
3959 /* -- Eliminating Frame Pointer and Arg Pointer. */
3962 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
3964 HOST_WIDE_INT offset
;
3966 /* Compute and setup stack frame size.
3967 The result will be in cfun->machine. */
3968 nds32_compute_stack_frame ();
3970 /* Remember to consider
3971 cfun->machine->callee_saved_area_gpr_padding_bytes and
3972 cfun->machine->eh_return_data_regs_size
3973 when calculating offset. */
3974 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
3976 offset
= (cfun
->machine
->fp_size
3977 + cfun
->machine
->gp_size
3978 + cfun
->machine
->lp_size
3979 + cfun
->machine
->callee_saved_gpr_regs_size
3980 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
3981 + cfun
->machine
->callee_saved_fpr_regs_size
3982 + cfun
->machine
->eh_return_data_regs_size
3983 + cfun
->machine
->local_size
3984 + cfun
->machine
->out_args_size
);
3986 else if (from_reg
== ARG_POINTER_REGNUM
3987 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3991 else if (from_reg
== FRAME_POINTER_REGNUM
3992 && to_reg
== STACK_POINTER_REGNUM
)
3994 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
3996 else if (from_reg
== FRAME_POINTER_REGNUM
3997 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3999 offset
= (-1) * (cfun
->machine
->fp_size
4000 + cfun
->machine
->gp_size
4001 + cfun
->machine
->lp_size
4002 + cfun
->machine
->callee_saved_gpr_regs_size
4003 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4004 + cfun
->machine
->callee_saved_fpr_regs_size
4005 + cfun
->machine
->eh_return_data_regs_size
);
4015 /* -- Passing Arguments in Registers. */
4018 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4019 tree fntype ATTRIBUTE_UNUSED
,
4020 rtx libname ATTRIBUTE_UNUSED
,
4021 tree fndecl ATTRIBUTE_UNUSED
,
4022 int n_named_args ATTRIBUTE_UNUSED
)
4024 /* Initial available registers. The values are offset against
4025 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
4026 for passing arguments. */
4027 cum
->gpr_offset
= 0;
4028 cum
->fpr_offset
= 0;
4031 /* -- Function Entry and Exit. */
4033 /* Function for normal multiple push prologue. */
4035 nds32_expand_prologue (void)
4041 /* Compute and setup stack frame size.
4042 The result will be in cfun->machine. */
4043 nds32_compute_stack_frame ();
4045 /* If this is a variadic function, first we need to push argument
4046 registers that hold the unnamed argument value. */
4047 if (cfun
->machine
->va_args_size
!= 0)
4049 Rb
= cfun
->machine
->va_args_first_regno
;
4050 Re
= cfun
->machine
->va_args_last_regno
;
4051 /* No need to push $fp, $gp, or $lp. */
4052 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, true);
4054 /* We may also need to adjust stack pointer for padding bytes
4055 because varargs may cause $sp not 8-byte aligned. */
4056 if (cfun
->machine
->va_args_area_padding_bytes
)
4058 /* Generate sp adjustment instruction. */
4059 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
4061 nds32_emit_adjust_frame (stack_pointer_rtx
,
4067 /* If the function is 'naked',
4068 we do not have to generate prologue code fragment. */
4069 if (cfun
->machine
->naked_p
)
4072 /* Get callee_first_regno and callee_last_regno. */
4073 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4074 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4076 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4077 to be saved, we don't have to create multiple push instruction.
4078 Otherwise, a multiple push instruction is needed. */
4079 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4080 && cfun
->machine
->fp_size
== 0
4081 && cfun
->machine
->gp_size
== 0
4082 && cfun
->machine
->lp_size
== 0))
4084 /* Create multiple push instruction rtx. */
4085 nds32_emit_stack_push_multiple (
4087 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
,
4091 /* Save eh data registers. */
4092 if (cfun
->machine
->use_eh_return_p
)
4094 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4095 Re
= cfun
->machine
->eh_return_data_last_regno
;
4097 /* No need to push $fp, $gp, or $lp.
4098 Also, this is not variadic arguments push. */
4099 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, false);
4102 /* Check frame_pointer_needed to see
4103 if we shall emit fp adjustment instruction. */
4104 if (frame_pointer_needed
)
4106 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
4107 + (4 * callee-saved-registers)
4108 + (4 * exception-handling-data-registers)
4109 Note: No need to adjust
4110 cfun->machine->callee_saved_area_gpr_padding_bytes,
4111 because, at this point, stack pointer is just
4112 at the position after push instruction. */
4113 fp_adjust
= cfun
->machine
->fp_size
4114 + cfun
->machine
->gp_size
4115 + cfun
->machine
->lp_size
4116 + cfun
->machine
->callee_saved_gpr_regs_size
4117 + cfun
->machine
->eh_return_data_regs_size
;
4119 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4124 /* Save fpu registers. */
4125 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4127 /* When $sp moved to bottom of stack, we need to check whether
4128 the range of offset in the FPU instruction. */
4129 int fpr_offset
= cfun
->machine
->local_size
4130 + cfun
->machine
->out_args_size
4131 + cfun
->machine
->callee_saved_fpr_regs_size
;
4133 /* Check FPU instruction offset imm14s. */
4134 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset
)))
4136 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4137 + cfun
->machine
->callee_saved_fpr_regs_size
;
4139 /* Save fpu registers, need to allocate stack space
4140 for fpu callee registers. And now $sp position
4141 on callee saved fpr registers. */
4142 nds32_emit_adjust_frame (stack_pointer_rtx
,
4146 /* Emit fpu store instruction, using [$sp + offset] store
4148 nds32_emit_push_fpr_callee_saved (0);
4150 /* Adjust $sp = $sp - local_size - out_args_size. */
4151 sp_adjust
= cfun
->machine
->local_size
4152 + cfun
->machine
->out_args_size
;
4154 /* Allocate stack space for local size and out args size. */
4155 nds32_emit_adjust_frame (stack_pointer_rtx
,
4161 /* Offset range in Is14, so $sp moved to bottom of stack. */
4163 /* Adjust $sp = $sp - local_size - out_args_size
4164 - callee_saved_area_gpr_padding_bytes
4165 - callee_saved_fpr_regs_size. */
4166 sp_adjust
= cfun
->machine
->local_size
4167 + cfun
->machine
->out_args_size
4168 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4169 + cfun
->machine
->callee_saved_fpr_regs_size
;
4171 nds32_emit_adjust_frame (stack_pointer_rtx
,
4175 /* Emit fpu store instruction, using [$sp + offset] store
4177 int fpr_position
= cfun
->machine
->out_args_size
4178 + cfun
->machine
->local_size
;
4179 nds32_emit_push_fpr_callee_saved (fpr_position
);
4184 /* Adjust $sp = $sp - local_size - out_args_size
4185 - callee_saved_area_gpr_padding_bytes. */
4186 sp_adjust
= cfun
->machine
->local_size
4187 + cfun
->machine
->out_args_size
4188 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4190 /* sp_adjust value may be out of range of the addi instruction,
4191 create alternative add behavior with TA_REGNUM if necessary,
4192 using NEGATIVE value to tell that we are decreasing address. */
4193 nds32_emit_adjust_frame (stack_pointer_rtx
,
4198 /* Prevent the instruction scheduler from
4199 moving instructions across the boundary. */
4200 emit_insn (gen_blockage ());
4203 /* Function for normal multiple pop epilogue. */
4205 nds32_expand_epilogue (bool sibcall_p
)
4210 /* Compute and setup stack frame size.
4211 The result will be in cfun->machine. */
4212 nds32_compute_stack_frame ();
4214 /* Prevent the instruction scheduler from
4215 moving instructions across the boundary. */
4216 emit_insn (gen_blockage ());
4218 /* If the function is 'naked', we do not have to generate
4219 epilogue code fragment BUT 'ret' instruction.
4220 However, if this function is also a variadic function,
4221 we need to create adjust stack pointer before 'ret' instruction. */
4222 if (cfun
->machine
->naked_p
)
4224 /* If this is a variadic function, we do not have to restore argument
4225 registers but need to adjust stack pointer back to previous stack
4226 frame location before return. */
4227 if (cfun
->machine
->va_args_size
!= 0)
4229 /* Generate sp adjustment instruction.
4230 We need to consider padding bytes here. */
4231 sp_adjust
= cfun
->machine
->va_args_size
4232 + cfun
->machine
->va_args_area_padding_bytes
;
4234 nds32_emit_adjust_frame (stack_pointer_rtx
,
4239 /* Generate return instruction by using 'return_internal' pattern.
4240 Make sure this instruction is after gen_blockage(). */
4242 emit_jump_insn (gen_return_internal ());
4246 if (frame_pointer_needed
)
4248 /* Restore fpu registers. */
4249 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4251 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4253 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4254 - (4 * callee-saved-registers)
4255 - (4 * exception-handling-data-registers)
4256 - (4 * callee-saved-gpr-registers padding byte)
4257 - (4 * callee-saved-fpr-registers)
4258 Note: we want to adjust stack pointer
4259 to the position for callee-saved fpr register,
4260 And restore fpu register use .bi instruction to adjust $sp
4261 from callee-saved fpr register to pop instruction. */
4262 sp_adjust
= cfun
->machine
->fp_size
4263 + cfun
->machine
->gp_size
4264 + cfun
->machine
->lp_size
4265 + cfun
->machine
->callee_saved_gpr_regs_size
4266 + cfun
->machine
->eh_return_data_regs_size
4267 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4268 + cfun
->machine
->callee_saved_fpr_regs_size
;
4270 nds32_emit_adjust_frame (stack_pointer_rtx
,
4271 hard_frame_pointer_rtx
,
4274 /* Emit fpu load instruction, using .bi instruction
4275 load fpu registers. */
4276 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4280 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4281 - (4 * callee-saved-registers)
4282 - (4 * exception-handling-data-registers)
4283 Note: No need to adjust
4284 cfun->machine->callee_saved_area_gpr_padding_bytes,
4285 because we want to adjust stack pointer
4286 to the position for pop instruction. */
4287 sp_adjust
= cfun
->machine
->fp_size
4288 + cfun
->machine
->gp_size
4289 + cfun
->machine
->lp_size
4290 + cfun
->machine
->callee_saved_gpr_regs_size
4291 + cfun
->machine
->eh_return_data_regs_size
;
4293 nds32_emit_adjust_frame (stack_pointer_rtx
,
4294 hard_frame_pointer_rtx
,
4300 /* Restore fpu registers. */
4301 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4303 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4305 /* Adjust $sp = $sp + local_size + out_args_size. */
4306 sp_adjust
= cfun
->machine
->local_size
4307 + cfun
->machine
->out_args_size
;
4309 nds32_emit_adjust_frame (stack_pointer_rtx
,
4313 /* Emit fpu load instruction, using .bi instruction
4314 load fpu registers, and adjust $sp from callee-saved fpr register
4315 to callee-saved gpr register. */
4316 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4320 /* If frame pointer is NOT needed,
4321 we cannot calculate the sp adjustment from frame pointer.
4322 Instead, we calculate the adjustment by local_size,
4323 out_args_size, and callee_saved_area_gpr_padding_bytes.
4324 Notice that such sp adjustment value may be out of range,
4325 so we have to deal with it as well. */
4327 /* Adjust $sp = $sp + local_size + out_args_size
4328 + callee_saved_area_gpr_padding_bytes. */
4329 sp_adjust
= cfun
->machine
->local_size
4330 + cfun
->machine
->out_args_size
4331 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4333 nds32_emit_adjust_frame (stack_pointer_rtx
,
4339 /* Restore eh data registers. */
4340 if (cfun
->machine
->use_eh_return_p
)
4342 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4343 Re
= cfun
->machine
->eh_return_data_last_regno
;
4345 /* No need to pop $fp, $gp, or $lp. */
4346 nds32_emit_stack_pop_multiple (Rb
, Re
, false, false, false);
4349 /* Get callee_first_regno and callee_last_regno. */
4350 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4351 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4353 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4354 to be saved, we don't have to create multiple pop instruction.
4355 Otherwise, a multiple pop instruction is needed. */
4356 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4357 && cfun
->machine
->fp_size
== 0
4358 && cfun
->machine
->gp_size
== 0
4359 && cfun
->machine
->lp_size
== 0))
4361 /* Create multiple pop instruction rtx. */
4362 nds32_emit_stack_pop_multiple (
4364 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
);
4367 /* If this is a variadic function, we do not have to restore argument
4368 registers but need to adjust stack pointer back to previous stack
4369 frame location before return. */
4370 if (cfun
->machine
->va_args_size
!= 0)
4372 /* Generate sp adjustment instruction.
4373 We need to consider padding bytes here. */
4374 sp_adjust
= cfun
->machine
->va_args_size
4375 + cfun
->machine
->va_args_area_padding_bytes
;
4377 nds32_emit_adjust_frame (stack_pointer_rtx
,
4382 /* If this function uses __builtin_eh_return, make stack adjustment
4383 for exception handler. */
4384 if (cfun
->machine
->use_eh_return_p
)
4386 /* We need to unwind the stack by the offset computed by
4387 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4388 based on SP. Ideally we would update the SP and define the
4389 CFA along the lines of:
4391 SP = SP + EH_RETURN_STACKADJ_RTX
4392 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4394 However the dwarf emitter only understands a constant
4397 The solution chosen here is to use the otherwise $ta ($r15)
4398 as a temporary register to hold the current SP value. The
4399 CFA is described using $ta then SP is modified. */
4404 ta_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
4406 insn
= emit_move_insn (ta_reg
, stack_pointer_rtx
);
4407 add_reg_note (insn
, REG_CFA_DEF_CFA
, ta_reg
);
4408 RTX_FRAME_RELATED_P (insn
) = 1;
4410 emit_insn (gen_addsi3 (stack_pointer_rtx
,
4412 EH_RETURN_STACKADJ_RTX
));
4414 /* Ensure the assignment to $ta does not get optimized away. */
4418 /* Generate return instruction. */
4420 emit_jump_insn (gen_return_internal ());
4423 /* Function for v3push prologue. */
4425 nds32_expand_prologue_v3push (void)
4432 /* Compute and setup stack frame size.
4433 The result will be in cfun->machine. */
4434 nds32_compute_stack_frame ();
4436 if (cfun
->machine
->callee_saved_gpr_regs_size
> 0)
4437 df_set_regs_ever_live (FP_REGNUM
, 1);
4439 /* If the function is 'naked',
4440 we do not have to generate prologue code fragment. */
4441 if (cfun
->machine
->naked_p
)
4444 /* Get callee_first_regno and callee_last_regno. */
4445 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4446 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4448 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
4449 where imm8u has to be 8-byte alignment. */
4450 sp_adjust
= cfun
->machine
->local_size
4451 + cfun
->machine
->out_args_size
4452 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4453 + cfun
->machine
->callee_saved_fpr_regs_size
;
4455 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4456 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
4458 /* We can use 'push25 Re,imm8u'. */
4460 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4461 the pattern 'stack_v3push' is implemented in nds32.md. */
4462 nds32_emit_stack_v3push (Rb
, Re
, sp_adjust
);
4464 /* Save fpu registers. */
4465 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4467 /* Calculate fpr position. */
4468 int fpr_position
= cfun
->machine
->local_size
4469 + cfun
->machine
->out_args_size
;
4470 /* Emit fpu store instruction, using [$sp + offset] store
4472 nds32_emit_push_fpr_callee_saved (fpr_position
);
4475 /* Check frame_pointer_needed to see
4476 if we shall emit fp adjustment instruction. */
4477 if (frame_pointer_needed
)
4479 /* adjust $fp = $sp + 4 ($fp size)
4482 + (4 * n) (callee-saved registers)
4483 + sp_adjust ('push25 Re,imm8u')
4484 Note: Since we use 'push25 Re,imm8u',
4485 the position of stack pointer is further
4486 changed after push instruction.
4487 Hence, we need to take sp_adjust value
4488 into consideration. */
4489 fp_adjust
= cfun
->machine
->fp_size
4490 + cfun
->machine
->gp_size
4491 + cfun
->machine
->lp_size
4492 + cfun
->machine
->callee_saved_gpr_regs_size
4495 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4502 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4504 /* Calculate fpr space. */
4505 fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4506 + cfun
->machine
->callee_saved_fpr_regs_size
;
4508 /* We have to use 'push25 Re, fpr_space', to pre-allocate
4509 callee saved fpr registers space. */
4510 nds32_emit_stack_v3push (Rb
, Re
, fpr_space
);
4511 nds32_emit_push_fpr_callee_saved (0);
4515 /* We have to use 'push25 Re,0' and
4516 expand one more instruction to adjust $sp later. */
4518 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4519 the pattern 'stack_v3push' is implemented in nds32.md. */
4520 nds32_emit_stack_v3push (Rb
, Re
, 0);
4523 /* Check frame_pointer_needed to see
4524 if we shall emit fp adjustment instruction. */
4525 if (frame_pointer_needed
)
4527 /* adjust $fp = $sp + 4 ($fp size)
4530 + (4 * n) (callee-saved registers)
4531 Note: Since we use 'push25 Re,0',
4532 the stack pointer is just at the position
4533 after push instruction.
4534 No need to take sp_adjust into consideration. */
4535 fp_adjust
= cfun
->machine
->fp_size
4536 + cfun
->machine
->gp_size
4537 + cfun
->machine
->lp_size
4538 + cfun
->machine
->callee_saved_gpr_regs_size
;
4540 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4542 /* We use 'push25 Re, fpr_space', the $sp is
4543 on callee saved fpr position, so need to consider
4545 fp_adjust
= fp_adjust
+ fpr_space
;
4548 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4553 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4555 /* We use 'push25 Re, fpr_space',
4556 the $sp is on callee saved fpr position,
4557 no need to consider fpr space. */
4558 sp_adjust
= sp_adjust
- fpr_space
;
4561 /* Because we use 'push25 Re,0',
4562 we need to expand one more instruction to adjust $sp.
4563 using NEGATIVE value to tell that we are decreasing address. */
4564 nds32_emit_adjust_frame (stack_pointer_rtx
,
4569 /* Prevent the instruction scheduler from
4570 moving instructions across the boundary. */
4571 emit_insn (gen_blockage ());
4574 /* Function for v3pop epilogue. */
4576 nds32_expand_epilogue_v3pop (bool sibcall_p
)
4581 /* Compute and setup stack frame size.
4582 The result will be in cfun->machine. */
4583 nds32_compute_stack_frame ();
4585 /* Prevent the instruction scheduler from
4586 moving instructions across the boundary. */
4587 emit_insn (gen_blockage ());
4589 /* If the function is 'naked', we do not have to generate
4590 epilogue code fragment BUT 'ret' instruction. */
4591 if (cfun
->machine
->naked_p
)
4593 /* Generate return instruction by using 'return_internal' pattern.
4594 Make sure this instruction is after gen_blockage(). */
4596 emit_jump_insn (gen_return_internal ());
4600 /* Get callee_first_regno and callee_last_regno. */
4601 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4602 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4604 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
4605 where imm8u has to be 8-byte alignment. */
4606 sp_adjust
= cfun
->machine
->local_size
4607 + cfun
->machine
->out_args_size
4608 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4609 + cfun
->machine
->callee_saved_fpr_regs_size
;
4611 /* We have to consider alloca issue as well.
4612 If the function does call alloca(), the stack pointer is not fixed.
4613 In that case, we cannot use 'pop25 Re,imm8u' directly.
4614 We have to caculate stack pointer from frame pointer
4615 and then use 'pop25 Re,0'.
4616 Of course, the frame_pointer_needed should be nonzero
4617 if the function calls alloca(). */
4618 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4619 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4620 && !cfun
->calls_alloca
)
4622 /* Restore fpu registers. */
4623 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4625 int fpr_position
= cfun
->machine
->local_size
4626 + cfun
->machine
->out_args_size
;
4627 /* Emit fpu load instruction, using [$sp + offset] restore
4629 nds32_emit_v3pop_fpr_callee_saved (fpr_position
);
4632 /* We can use 'pop25 Re,imm8u'. */
4634 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4635 the pattern 'stack_v3pop' is implementad in nds32.md. */
4636 nds32_emit_stack_v3pop (Rb
, Re
, sp_adjust
);
4640 /* We have to use 'pop25 Re,0', and prior to it,
4641 we must expand one more instruction to adjust $sp. */
4643 if (frame_pointer_needed
)
4645 /* adjust $sp = $fp - 4 ($fp size)
4648 - (4 * n) (callee-saved registers)
4649 Note: No need to adjust
4650 cfun->machine->callee_saved_area_gpr_padding_bytes,
4651 because we want to adjust stack pointer
4652 to the position for pop instruction. */
4653 sp_adjust
= cfun
->machine
->fp_size
4654 + cfun
->machine
->gp_size
4655 + cfun
->machine
->lp_size
4656 + cfun
->machine
->callee_saved_gpr_regs_size
;
4658 /* Restore fpu registers. */
4659 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4661 /* Set $sp to callee saved fpr position, we need to restore
4663 sp_adjust
= sp_adjust
4664 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4665 + cfun
->machine
->callee_saved_fpr_regs_size
;
4667 nds32_emit_adjust_frame (stack_pointer_rtx
,
4668 hard_frame_pointer_rtx
,
4671 /* Emit fpu load instruction, using [$sp + offset] restore
4673 nds32_emit_v3pop_fpr_callee_saved (0);
4677 nds32_emit_adjust_frame (stack_pointer_rtx
,
4678 hard_frame_pointer_rtx
,
4684 /* If frame pointer is NOT needed,
4685 we cannot calculate the sp adjustment from frame pointer.
4686 Instead, we calculate the adjustment by local_size,
4687 out_args_size, and callee_saved_area_padding_bytes.
4688 Notice that such sp adjustment value may be out of range,
4689 so we have to deal with it as well. */
4691 /* Adjust $sp = $sp + local_size + out_args_size
4692 + callee_saved_area_gpr_padding_bytes
4693 + callee_saved_fpr_regs_size. */
4694 sp_adjust
= cfun
->machine
->local_size
4695 + cfun
->machine
->out_args_size
4696 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4697 + cfun
->machine
->callee_saved_fpr_regs_size
;
4699 /* Restore fpu registers. */
4700 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4702 /* Set $sp to callee saved fpr position, we need to restore
4704 sp_adjust
= sp_adjust
4705 - cfun
->machine
->callee_saved_area_gpr_padding_bytes
4706 - cfun
->machine
->callee_saved_fpr_regs_size
;
4708 nds32_emit_adjust_frame (stack_pointer_rtx
,
4712 /* Emit fpu load instruction, using [$sp + offset] restore
4714 nds32_emit_v3pop_fpr_callee_saved (0);
4718 /* sp_adjust value may be out of range of the addi instruction,
4719 create alternative add behavior with TA_REGNUM if necessary,
4720 using POSITIVE value to tell that we are increasing
4722 nds32_emit_adjust_frame (stack_pointer_rtx
,
4728 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4730 /* We have fpr need to restore, so $sp is set on callee saved fpr
4731 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
4732 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4733 + cfun
->machine
->callee_saved_fpr_regs_size
;
4734 nds32_emit_stack_v3pop (Rb
, Re
, fpr_space
);
4738 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4739 the pattern 'stack_v3pop' is implementad in nds32.md. */
4740 nds32_emit_stack_v3pop (Rb
, Re
, 0);
4743 /* Generate return instruction. */
4744 emit_jump_insn (gen_pop25return ());
4747 /* Return nonzero if this function is known to have a null epilogue.
4748 This allows the optimizer to omit jumps to jumps if no stack
4751 nds32_can_use_return_insn (void)
4755 /* Prior to reloading, we can't tell how many registers must be saved.
4756 Thus we can not determine whether this function has null epilogue. */
4757 if (!reload_completed
)
4760 sp_adjust
= cfun
->machine
->local_size
4761 + cfun
->machine
->out_args_size
4762 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4763 + cfun
->machine
->callee_saved_fpr_regs_size
;
4764 if (!cfun
->machine
->fp_as_gp_p
4765 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4766 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4767 && !cfun
->calls_alloca
4768 && NDS32_V3PUSH_AVAILABLE_P
4769 && !(TARGET_HARD_FLOAT
4770 && (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)))
4773 /* If no stack was created, two conditions must be satisfied:
4774 1. This is a naked function.
4775 So there is no callee-saved, local size, or outgoing size.
4776 2. This is NOT a variadic function.
4777 So there is no pushing arguement registers into the stack. */
4778 return (cfun
->machine
->naked_p
&& (cfun
->machine
->va_args_size
== 0));
4782 nds32_case_vector_shorten_mode (int min_offset
, int max_offset
,
4783 rtx body ATTRIBUTE_UNUSED
)
4785 if (min_offset
< 0 || max_offset
>= 0x2000)
4789 /* The jump table maybe need to 2 byte alignment,
4790 so reserved 1 byte for check max_offset. */
4791 if (max_offset
>= 0xff)
4798 /* ------------------------------------------------------------------------ */
4800 /* Return alignment for the label. */
4802 nds32_target_alignment (rtx_insn
*label
)
4806 if (!NDS32_ALIGN_P ())
4809 insn
= next_active_insn (label
);
4811 /* Always align to 4 byte when first instruction after label is jump
4812 instruction since length for that might changed, so let's always align
4813 it for make sure we don't lose any perfomance here. */
4815 || (get_attr_length (insn
) == 2
4816 && !JUMP_P (insn
) && !CALL_P (insn
)))
4822 /* Return alignment for data. */
4824 nds32_data_alignment (tree data
,
4825 unsigned int basic_align
)
4827 if ((basic_align
< BITS_PER_WORD
)
4828 && (TREE_CODE (data
) == ARRAY_TYPE
4829 || TREE_CODE (data
) == UNION_TYPE
4830 || TREE_CODE (data
) == RECORD_TYPE
))
4831 return BITS_PER_WORD
;
4836 /* Return alignment for constant value. */
4837 static HOST_WIDE_INT
4838 nds32_constant_alignment (const_tree constant
,
4839 HOST_WIDE_INT basic_align
)
4841 /* Make string literal and constant for constructor to word align. */
4842 if (((TREE_CODE (constant
) == STRING_CST
4843 || TREE_CODE (constant
) == CONSTRUCTOR
4844 || TREE_CODE (constant
) == UNION_TYPE
4845 || TREE_CODE (constant
) == RECORD_TYPE
4846 || TREE_CODE (constant
) == ARRAY_TYPE
)
4847 && basic_align
< BITS_PER_WORD
))
4848 return BITS_PER_WORD
;
4853 /* Return alignment for local variable. */
4855 nds32_local_alignment (tree local ATTRIBUTE_UNUSED
,
4856 unsigned int basic_align
)
4858 bool at_least_align_to_word
= false;
4859 /* Make local array, struct and union at least align to word for make
4860 sure it can unroll memcpy when initialize by constant. */
4861 switch (TREE_CODE (local
))
4866 at_least_align_to_word
= true;
4869 at_least_align_to_word
= false;
4872 if (at_least_align_to_word
4873 && (basic_align
< BITS_PER_WORD
))
4874 return BITS_PER_WORD
;
4880 nds32_split_double_word_load_store_p(rtx
*operands
, bool load_p
)
4882 rtx mem
= load_p
? operands
[1] : operands
[0];
4883 /* Do split at split2 if -O0 or schedule 2 not enable. */
4884 if (optimize
== 0 || !flag_schedule_insns_after_reload
)
4885 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4887 /* Split double word load store after copy propgation. */
4888 if (current_pass
== NULL
)
4891 const char *pass_name
= current_pass
->name
;
4892 if (pass_name
&& ((strcmp (pass_name
, "split4") == 0)
4893 || (strcmp (pass_name
, "split5") == 0)))
4894 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4900 nds32_use_blocks_for_constant_p (machine_mode mode
,
4901 const_rtx x ATTRIBUTE_UNUSED
)
4903 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
4904 && (mode
== DFmode
|| mode
== SFmode
))
4910 /* ------------------------------------------------------------------------ */
4912 /* PART 5: Initialize target hook structure and definitions. */
4914 /* Controlling the Compilation Driver. */
4917 /* Run-time Target Specification. */
4920 /* Defining Data Structures for Per-function Information. */
4923 /* Storage Layout. */
4925 #undef TARGET_PROMOTE_FUNCTION_MODE
4926 #define TARGET_PROMOTE_FUNCTION_MODE \
4927 default_promote_function_mode_always_promote
4929 #undef TARGET_EXPAND_TO_RTL_HOOK
4930 #define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
4932 #undef TARGET_CONSTANT_ALIGNMENT
4933 #define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment
4936 /* Layout of Source Language Data Types. */
4939 /* Register Usage. */
4941 /* -- Basic Characteristics of Registers. */
4943 #undef TARGET_CONDITIONAL_REGISTER_USAGE
4944 #define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
4946 /* -- Order of Allocation of Registers. */
4948 /* -- How Values Fit in Registers. */
4950 #undef TARGET_HARD_REGNO_NREGS
4951 #define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
4953 #undef TARGET_HARD_REGNO_MODE_OK
4954 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
4956 #undef TARGET_MODES_TIEABLE_P
4957 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
4959 /* -- Handling Leaf Functions. */
4961 /* -- Registers That Form a Stack. */
4964 /* Register Classes. */
4966 #undef TARGET_CLASS_MAX_NREGS
4967 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
4969 #undef TARGET_REGISTER_PRIORITY
4970 #define TARGET_REGISTER_PRIORITY nds32_register_priority
4972 #undef TARGET_CAN_CHANGE_MODE_CLASS
4973 #define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
4976 /* Obsolete Macros for Defining Constraints. */
4979 /* Stack Layout and Calling Conventions. */
4981 /* -- Basic Stack Layout. */
4983 /* -- Exception Handling Support. */
4985 /* -- Specifying How Stack Checking is Done. */
4987 /* -- Registers That Address the Stack Frame. */
4989 /* -- Eliminating Frame Pointer and Arg Pointer. */
4991 #undef TARGET_CAN_ELIMINATE
4992 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
4994 /* -- Passing Function Arguments on the Stack. */
4996 /* -- Passing Arguments in Registers. */
4998 #undef TARGET_FUNCTION_ARG
4999 #define TARGET_FUNCTION_ARG nds32_function_arg
5001 #undef TARGET_MUST_PASS_IN_STACK
5002 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
5004 #undef TARGET_ARG_PARTIAL_BYTES
5005 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
5007 #undef TARGET_FUNCTION_ARG_ADVANCE
5008 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5010 #undef TARGET_FUNCTION_ARG_BOUNDARY
5011 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5013 /* -- How Scalar Function Values Are Returned. */
5015 #undef TARGET_FUNCTION_VALUE
5016 #define TARGET_FUNCTION_VALUE nds32_function_value
5018 #undef TARGET_LIBCALL_VALUE
5019 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5021 #undef TARGET_FUNCTION_VALUE_REGNO_P
5022 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5024 /* -- How Large Values Are Returned. */
5026 #undef TARGET_RETURN_IN_MEMORY
5027 #define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
5029 /* -- Caller-Saves Register Allocation. */
5031 /* -- Function Entry and Exit. */
5033 #undef TARGET_ASM_FUNCTION_PROLOGUE
5034 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5036 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5037 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5039 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5040 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5042 #undef TARGET_ASM_FUNCTION_EPILOGUE
5043 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5045 #undef TARGET_ASM_OUTPUT_MI_THUNK
5046 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5048 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5049 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5051 /* -- Generating Code for Profiling. */
5053 /* -- Permitting tail calls. */
5055 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5056 #define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
5058 #undef TARGET_WARN_FUNC_RETURN
5059 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5061 /* Stack smashing protection. */
5064 /* Implementing the Varargs Macros. */
5066 #undef TARGET_SETUP_INCOMING_VARARGS
5067 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5069 #undef TARGET_STRICT_ARGUMENT_NAMING
5070 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5073 /* Trampolines for Nested Functions. */
5075 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5076 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5078 #undef TARGET_TRAMPOLINE_INIT
5079 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5082 /* Implicit Calls to Library Routines. */
5085 /* Addressing Modes. */
5087 #undef TARGET_LEGITIMATE_ADDRESS_P
5088 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5091 /* Anchored Addresses. */
5094 /* Condition Code Status. */
5096 /* -- Representation of condition codes using (cc0). */
5098 /* -- Representation of condition codes using registers. */
5100 #undef TARGET_CANONICALIZE_COMPARISON
5101 #define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5103 /* -- Macros to control conditional execution. */
5106 /* Describing Relative Costs of Operations. */
5108 #undef TARGET_REGISTER_MOVE_COST
5109 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5111 #undef TARGET_MEMORY_MOVE_COST
5112 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5114 #undef TARGET_RTX_COSTS
5115 #define TARGET_RTX_COSTS nds32_rtx_costs
5117 #undef TARGET_ADDRESS_COST
5118 #define TARGET_ADDRESS_COST nds32_address_cost
5121 /* Adjusting the Instruction Scheduler. */
5124 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5126 #undef TARGET_ENCODE_SECTION_INFO
5127 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5130 /* Position Independent Code. */
5133 /* Defining the Output Assembler Language. */
5135 /* -- The Overall Framework of an Assembler File. */
5137 #undef TARGET_ASM_FILE_START
5138 #define TARGET_ASM_FILE_START nds32_asm_file_start
5139 #undef TARGET_ASM_FILE_END
5140 #define TARGET_ASM_FILE_END nds32_asm_file_end
5142 /* -- Output of Data. */
5144 #undef TARGET_ASM_ALIGNED_HI_OP
5145 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5147 #undef TARGET_ASM_ALIGNED_SI_OP
5148 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5150 /* -- Output of Uninitialized Variables. */
5152 /* -- Output and Generation of Labels. */
5154 #undef TARGET_ASM_GLOBALIZE_LABEL
5155 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5157 /* -- How Initialization Functions Are Handled. */
5159 /* -- Macros Controlling Initialization Routines. */
5161 /* -- Output of Assembler Instructions. */
5163 #undef TARGET_PRINT_OPERAND
5164 #define TARGET_PRINT_OPERAND nds32_print_operand
5165 #undef TARGET_PRINT_OPERAND_ADDRESS
5166 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5168 /* -- Output of Dispatch Tables. */
5170 /* -- Assembler Commands for Exception Regions. */
5172 #undef TARGET_DWARF_REGISTER_SPAN
5173 #define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5175 /* -- Assembler Commands for Alignment. */
5178 /* Controlling Debugging Information Format. */
5180 /* -- Macros Affecting All Debugging Formats. */
5182 /* -- Specific Options for DBX Output. */
5184 /* -- Open-Ended Hooks for DBX Format. */
5186 /* -- File Names in DBX Format. */
5188 /* -- Macros for DWARF Output. */
5190 /* -- Macros for VMS Debug Format. */
5193 /* Cross Compilation and Floating Point. */
5196 /* Mode Switching Instructions. */
5199 /* Defining target-specific uses of __attribute__. */
5201 #undef TARGET_ATTRIBUTE_TABLE
5202 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5204 #undef TARGET_MERGE_DECL_ATTRIBUTES
5205 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5207 #undef TARGET_INSERT_ATTRIBUTES
5208 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5210 #undef TARGET_OPTION_PRAGMA_PARSE
5211 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5213 #undef TARGET_OPTION_OVERRIDE
5214 #define TARGET_OPTION_OVERRIDE nds32_option_override
5217 /* Emulating TLS. */
5220 /* Defining coprocessor specifics for MIPS targets. */
5223 /* Parameters for Precompiled Header Validity Checking. */
5226 /* C++ ABI parameters. */
5229 /* Adding support for named address spaces. */
5232 /* Miscellaneous Parameters. */
5234 #undef TARGET_MD_ASM_ADJUST
5235 #define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5237 #undef TARGET_INIT_BUILTINS
5238 #define TARGET_INIT_BUILTINS nds32_init_builtins
5240 #undef TARGET_BUILTIN_DECL
5241 #define TARGET_BUILTIN_DECL nds32_builtin_decl
5243 #undef TARGET_EXPAND_BUILTIN
5244 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5247 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5248 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5251 /* ------------------------------------------------------------------------ */
5253 /* Initialize the GCC target structure. */
5255 struct gcc_target targetm
= TARGET_INITIALIZER
;
5257 /* ------------------------------------------------------------------------ */