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 one_position
;
2948 HOST_WIDE_INT zero_position
;
2949 bool pick_lsb_p
= false;
2950 bool pick_msb_p
= false;
2958 /* Do nothing special. */
2962 /* Use exact_log2() to search the 0-bit position. */
2963 gcc_assert (CONST_INT_P (x
));
2964 zero_position
= exact_log2 (~UINTVAL (x
) & GET_MODE_MASK (SImode
));
2965 gcc_assert (zero_position
!= -1);
2966 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, zero_position
);
2968 /* No need to handle following process, so return immediately. */
2972 gcc_assert (MEM_P (x
)
2973 && GET_CODE (XEXP (x
, 0)) == PLUS
2974 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
2975 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (XEXP (XEXP (x
, 0), 1)));
2977 /* No need to handle following process, so return immediately. */
2980 /* Use exact_log2() to search the 1-bit position. */
2981 gcc_assert (CONST_INT_P (x
));
2982 one_position
= exact_log2 (UINTVAL (x
) & GET_MODE_MASK (SImode
));
2983 gcc_assert (one_position
!= -1);
2984 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, one_position
);
2986 /* No need to handle following process, so return immediately. */
2990 /* X is supposed to be REG rtx. */
2991 gcc_assert (REG_P (x
));
2992 /* Claim that we are going to pick LSB part of X. */
2997 /* X is supposed to be REG rtx. */
2998 gcc_assert (REG_P (x
));
2999 /* Claim that we are going to pick MSB part of X. */
3004 /* 'x' is supposed to be CONST_INT, get the value. */
3005 gcc_assert (CONST_INT_P (x
));
3006 op_value
= INTVAL (x
);
3008 /* According to the Andes architecture,
3009 the system/user register index range is 0 ~ 1023.
3010 In order to avoid conflict between user-specified-integer value
3011 and enum-specified-register value,
3012 the 'enum nds32_intrinsic_registers' value
3013 in nds32_intrinsic.h starts from 1024. */
3014 if (op_value
< 1024 && op_value
>= 0)
3016 /* If user gives integer value directly (0~1023),
3017 we just print out the value. */
3018 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, op_value
);
3020 else if (op_value
< 0
3021 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
3024 /* The enum index value for array size is out of range. */
3025 error ("intrinsic register index is out of range");
3029 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3030 we can print out register name. Remember to substract 1024. */
3031 fprintf (stream
, "%s",
3032 nds32_intrinsic_register_names
[op_value
- 1024]);
3035 /* No need to handle following process, so return immediately. */
3038 case 'R': /* cctl valck */
3039 /* Note the cctl divide to 5 group and share the same name table. */
3040 if (op_value
< 0 || op_value
> 4)
3041 error ("CCTL intrinsic function subtype out of range!");
3042 fprintf (stream
, "%s", nds32_cctl_names
[op_value
]);
3045 case 'T': /* cctl idxwbinv */
3046 /* Note the cctl divide to 5 group and share the same name table. */
3047 if (op_value
< 0 || op_value
> 4)
3048 error ("CCTL intrinsic function subtype out of range!");
3049 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 4]);
3052 case 'U': /* cctl vawbinv */
3053 /* Note the cctl divide to 5 group and share the same name table. */
3054 if (op_value
< 0 || op_value
> 4)
3055 error ("CCTL intrinsic function subtype out of range!");
3056 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 8]);
3059 case 'X': /* cctl idxread */
3060 /* Note the cctl divide to 5 group and share the same name table. */
3061 if (op_value
< 0 || op_value
> 4)
3062 error ("CCTL intrinsic function subtype out of range!");
3063 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 12]);
3066 case 'W': /* cctl idxwitre */
3067 /* Note the cctl divide to 5 group and share the same name table. */
3068 if (op_value
< 0 || op_value
> 4)
3069 error ("CCTL intrinsic function subtype out of range!");
3070 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 16]);
3073 case 'Z': /* dpref */
3074 fprintf (stream
, "%s", nds32_dpref_names
[op_value
]);
3079 output_operand_lossage ("invalid operand output code");
3083 switch (GET_CODE (x
))
3087 output_addr_const (stream
, x
);
3091 /* Print a Double-precision register name. */
3092 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3093 && NDS32_IS_FPR_REGNUM (REGNO (x
)))
3096 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
))
3098 output_operand_lossage ("invalid operand for code '%c'", code
);
3101 fprintf (stream
, "$fd%d", (regno
- NDS32_FIRST_FPR_REGNUM
) >> 1);
3105 /* Print LSB or MSB part of register pair if the
3106 constraint modifier 'L' or 'H' is specified. */
3107 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3108 && NDS32_IS_GPR_REGNUM (REGNO (x
)))
3110 if ((pick_lsb_p
&& WORDS_BIG_ENDIAN
)
3111 || (pick_msb_p
&& !WORDS_BIG_ENDIAN
))
3113 /* If we would like to print out LSB register under big-endian,
3114 or print out MSB register under little-endian, we need to
3115 increase register number. */
3118 fputs (reg_names
[regno
], stream
);
3123 /* Forbid using static chain register ($r16)
3124 on reduced-set registers configuration. */
3125 if (TARGET_REDUCED_REGS
3126 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3127 sorry ("a nested function is not supported for reduced registers");
3129 /* Normal cases, print out register name. */
3130 fputs (reg_names
[REGNO (x
)], stream
);
3134 output_address (GET_MODE (x
), XEXP (x
, 0));
3138 if (GET_CODE (XEXP (x
, 0)) == CONST_DOUBLE
)
3140 const REAL_VALUE_TYPE
*rv
;
3142 gcc_assert (GET_MODE (x
) == SFmode
);
3144 rv
= CONST_DOUBLE_REAL_VALUE (XEXP (x
, 0));
3145 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3147 fprintf (stream
, "hi20(0x%lx)", val
);
3154 const REAL_VALUE_TYPE
*rv
;
3156 gcc_assert (GET_MODE (x
) == SFmode
);
3158 rv
= CONST_DOUBLE_REAL_VALUE (x
);
3159 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3161 fprintf (stream
, "0x%lx", val
);
3167 output_addr_const (stream
, x
);
3171 /* Generally, output_addr_const () is able to handle most cases.
3172 We want to see what CODE could appear,
3173 so we use gcc_unreachable() to stop it. */
3181 nds32_print_operand_address (FILE *stream
, machine_mode
/*mode*/, rtx x
)
3185 switch (GET_CODE (x
))
3189 /* [ + symbol_ref] */
3190 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3191 fputs ("[ + ", stream
);
3192 output_addr_const (stream
, x
);
3193 fputs ("]", stream
);
3197 /* Forbid using static chain register ($r16)
3198 on reduced-set registers configuration. */
3199 if (TARGET_REDUCED_REGS
3200 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3201 sorry ("a nested function is not supported for reduced registers");
3204 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
3211 /* Checking op0, forbid using static chain register ($r16)
3212 on reduced-set registers configuration. */
3213 if (TARGET_REDUCED_REGS
3215 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3216 sorry ("a nested function is not supported for reduced registers");
3217 /* Checking op1, forbid using static chain register ($r16)
3218 on reduced-set registers configuration. */
3219 if (TARGET_REDUCED_REGS
3221 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3222 sorry ("a nested function is not supported for reduced registers");
3224 if (REG_P (op0
) && CONST_INT_P (op1
))
3227 fprintf (stream
, "[%s + (" HOST_WIDE_INT_PRINT_DEC
")]",
3228 reg_names
[REGNO (op0
)], INTVAL (op1
));
3230 else if (REG_P (op0
) && REG_P (op1
))
3233 fprintf (stream
, "[%s + %s]",
3234 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3236 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
3239 From observation, the pattern looks like:
3240 (plus:SI (mult:SI (reg:SI 58)
3241 (const_int 4 [0x4]))
3245 /* We need to set sv to output shift value. */
3246 if (INTVAL (XEXP (op0
, 1)) == 1)
3248 else if (INTVAL (XEXP (op0
, 1)) == 2)
3250 else if (INTVAL (XEXP (op0
, 1)) == 4)
3252 else if (INTVAL (XEXP (op0
, 1)) == 8)
3257 fprintf (stream
, "[%s + %s << %d]",
3258 reg_names
[REGNO (op1
)],
3259 reg_names
[REGNO (XEXP (op0
, 0))],
3264 /* The control flow is not supposed to be here. */
3272 /* (post_modify (regA) (plus (regA) (regB)))
3273 (post_modify (regA) (plus (regA) (const_int)))
3274 We would like to extract
3275 regA and regB (or const_int) from plus rtx. */
3276 op0
= XEXP (XEXP (x
, 1), 0);
3277 op1
= XEXP (XEXP (x
, 1), 1);
3279 /* Checking op0, forbid using static chain register ($r16)
3280 on reduced-set registers configuration. */
3281 if (TARGET_REDUCED_REGS
3283 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3284 sorry ("a nested function is not supported for reduced registers");
3285 /* Checking op1, forbid using static chain register ($r16)
3286 on reduced-set registers configuration. */
3287 if (TARGET_REDUCED_REGS
3289 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3290 sorry ("a nested function is not supported for reduced registers");
3292 if (REG_P (op0
) && REG_P (op1
))
3295 fprintf (stream
, "[%s], %s",
3296 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3298 else if (REG_P (op0
) && CONST_INT_P (op1
))
3301 fprintf (stream
, "[%s], " HOST_WIDE_INT_PRINT_DEC
,
3302 reg_names
[REGNO (op0
)], INTVAL (op1
));
3306 /* The control flow is not supposed to be here. */
3317 /* Checking op0, forbid using static chain register ($r16)
3318 on reduced-set registers configuration. */
3319 if (TARGET_REDUCED_REGS
3321 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3322 sorry ("a nested function is not supported for reduced registers");
3326 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3327 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3328 We only need to deal with register Ra. */
3329 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
3333 /* The control flow is not supposed to be here. */
3341 /* Generally, output_addr_const () is able to handle most cases.
3342 We want to see what CODE could appear,
3343 so we use gcc_unreachable() to stop it. */
3350 /* -- Assembler Commands for Exception Regions. */
3353 nds32_dwarf_register_span (rtx reg
)
3355 rtx dwarf_high
, dwarf_low
;
3360 mode
= GET_MODE (reg
);
3361 regno
= REGNO (reg
);
3363 /* We need to adjust dwarf register information for floating-point registers
3364 rather than using default register number mapping. */
3365 if (regno
>= NDS32_FIRST_FPR_REGNUM
3366 && regno
<= NDS32_LAST_FPR_REGNUM
)
3368 if (mode
== DFmode
|| mode
== SCmode
)
3370 /* By default, GCC maps increasing register numbers to increasing
3371 memory locations, but paired FPRs in NDS32 target are always
3377 We must return parallel rtx to represent such layout. */
3378 dwarf_high
= gen_rtx_REG (word_mode
, regno
);
3379 dwarf_low
= gen_rtx_REG (word_mode
, regno
+ 1);
3380 return gen_rtx_PARALLEL (VOIDmode
,
3381 gen_rtvec (2, dwarf_low
, dwarf_high
));
3383 else if (mode
== DCmode
)
3385 rtx dwarf_high_re
= gen_rtx_REG (word_mode
, regno
);
3386 rtx dwarf_low_re
= gen_rtx_REG (word_mode
, regno
+ 1);
3387 rtx dwarf_high_im
= gen_rtx_REG (word_mode
, regno
);
3388 rtx dwarf_low_im
= gen_rtx_REG (word_mode
, regno
+ 1);
3389 return gen_rtx_PARALLEL (VOIDmode
,
3390 gen_rtvec (4, dwarf_low_re
, dwarf_high_re
,
3391 dwarf_high_im
, dwarf_low_im
));
3393 else if (mode
== SFmode
|| mode
== SImode
)
3395 /* Create new dwarf information with adjusted register number. */
3396 dwarf_single
= gen_rtx_REG (word_mode
, regno
);
3397 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, dwarf_single
));
3401 /* We should not be here. */
3409 /* Map internal gcc register numbers to DWARF2 register numbers. */
3412 nds32_dbx_register_number (unsigned int regno
)
3414 /* The nds32 port in GDB maintains a mapping between dwarf register
3415 number and displayed register name. For backward compatibility to
3416 previous toolchain, currently our gdb still has four registers
3417 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3418 does not count those four registers in its register number table.
3419 So we have to add 4 on its register number and then create new
3420 dwarf information. Hopefully we can discard such workaround
3422 if (NDS32_IS_FPR_REGNUM (regno
))
3429 /* Defining target-specific uses of __attribute__. */
3431 /* Add some checking after merging attributes. */
3433 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
3435 tree combined_attrs
;
3437 /* Create combined attributes. */
3438 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
3439 DECL_ATTRIBUTES (newdecl
));
3441 /* Since newdecl is acutally a duplicate of olddecl,
3442 we can take olddecl for some operations. */
3443 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
3445 /* Check isr-specific attributes conflict. */
3446 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
3449 return combined_attrs
;
3452 /* Add some checking when inserting attributes. */
3454 nds32_insert_attributes (tree decl
, tree
*attributes
)
3456 /* For function declaration, we need to check isr-specific attributes:
3457 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3458 2. Check valid integer value for interrupt/exception.
3459 3. Check valid integer value for reset.
3460 4. Check valid function for nmi/warm. */
3461 if (TREE_CODE (decl
) == FUNCTION_DECL
)
3464 tree intr
, excp
, reset
;
3466 /* Pick up function attributes. */
3467 func_attrs
= *attributes
;
3469 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3470 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
3472 /* Now we are starting to check valid id value
3473 for interrupt/exception/reset.
3474 Note that we ONLY check its validity here.
3475 To construct isr vector information, it is still performed
3476 by nds32_construct_isr_vectors_information(). */
3477 intr
= lookup_attribute ("interrupt", func_attrs
);
3478 excp
= lookup_attribute ("exception", func_attrs
);
3479 reset
= lookup_attribute ("reset", func_attrs
);
3483 /* Deal with interrupt/exception. */
3485 unsigned int lower_bound
, upper_bound
;
3487 /* The way to handle interrupt or exception is the same,
3488 we just need to take care of actual vector number.
3489 For interrupt(0..63), the actual vector number is (9..72).
3490 For exception(1..8), the actual vector number is (1..8). */
3491 lower_bound
= (intr
) ? (0) : (1);
3492 upper_bound
= (intr
) ? (63) : (8);
3494 /* Prepare id list so that we can traverse id value. */
3495 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
3497 /* 2. Check valid integer value for interrupt/exception. */
3502 /* Pick up each vector id value. */
3503 id
= TREE_VALUE (id_list
);
3504 /* Issue error if it is not a valid integer value. */
3505 if (TREE_CODE (id
) != INTEGER_CST
3506 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3507 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3508 error ("invalid id value for interrupt/exception attribute");
3510 /* Advance to next id. */
3511 id_list
= TREE_CHAIN (id_list
);
3516 /* Deal with reset. */
3520 unsigned int lower_bound
;
3521 unsigned int upper_bound
;
3523 /* Prepare id_list and identify id value so that
3524 we can check if total number of vectors is valid. */
3525 id_list
= TREE_VALUE (reset
);
3526 id
= TREE_VALUE (id_list
);
3528 /* The maximum numbers for user's interrupt is 64. */
3532 /* 3. Check valid integer value for reset. */
3533 if (TREE_CODE (id
) != INTEGER_CST
3534 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3535 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3536 error ("invalid id value for reset attribute");
3538 /* 4. Check valid function for nmi/warm. */
3539 nmi
= lookup_attribute ("nmi", func_attrs
);
3540 warm
= lookup_attribute ("warm", func_attrs
);
3542 if (nmi
!= NULL_TREE
)
3547 nmi_func_list
= TREE_VALUE (nmi
);
3548 nmi_func
= TREE_VALUE (nmi_func_list
);
3550 /* Issue error if it is not a valid nmi function. */
3551 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
3552 error ("invalid nmi function for reset attribute");
3555 if (warm
!= NULL_TREE
)
3557 tree warm_func_list
;
3560 warm_func_list
= TREE_VALUE (warm
);
3561 warm_func
= TREE_VALUE (warm_func_list
);
3563 /* Issue error if it is not a valid warm function. */
3564 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
3565 error ("invalid warm function for reset attribute");
3570 /* No interrupt, exception, or reset attribute is set. */
3577 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
3578 tree pop_target ATTRIBUTE_UNUSED
)
3580 /* Currently, we do not parse any pragma target by ourself,
3581 so just simply return false. */
3586 nds32_option_override (void)
3588 /* After all the command options have been parsed,
3589 we shall deal with some flags for changing compiler settings. */
3591 /* At first, we check if we have to strictly
3592 set some flags based on ISA family. */
3595 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
3596 target_flags
&= ~MASK_V3PUSH
;
3600 /* Under V3 ISA, currently nothing should be strictly set. */
3604 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
3605 target_flags
|= MASK_REDUCED_REGS
;
3606 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
3607 target_flags
&= ~MASK_EXT_PERF
;
3608 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
3609 target_flags
&= ~MASK_EXT_PERF2
;
3610 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
3611 target_flags
&= ~MASK_EXT_STRING
;
3614 /* See if we are using reduced-set registers:
3615 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
3616 If so, we must forbid using $r11~$r14, $r16~$r27. */
3617 if (TARGET_REDUCED_REGS
)
3621 /* Prevent register allocator from
3622 choosing it as doing register allocation. */
3623 for (r
= 11; r
<= 14; r
++)
3624 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3625 for (r
= 16; r
<= 27; r
++)
3626 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3631 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
3632 target_flags
&= ~MASK_V3PUSH
;
3635 if (TARGET_HARD_FLOAT
&& !(TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
3637 if (nds32_arch_option
== ARCH_V3S
|| nds32_arch_option
== ARCH_V3F
)
3638 error ("Disable FPU ISA, "
3639 "the ABI option must be enable '-mfloat-abi=soft'");
3641 error ("'-mabi=2fp+' option only support when FPU available, "
3642 "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
3645 /* Currently, we don't support PIC code generation yet. */
3647 sorry ("position-independent code not supported");
3649 nds32_register_passes ();
3653 /* Miscellaneous Parameters. */
3656 nds32_md_asm_adjust (vec
<rtx
> &outputs ATTRIBUTE_UNUSED
,
3657 vec
<rtx
> &inputs ATTRIBUTE_UNUSED
,
3658 vec
<const char *> &constraints ATTRIBUTE_UNUSED
,
3659 vec
<rtx
> &clobbers
, HARD_REG_SET
&clobbered_regs
)
3661 clobbers
.safe_push (gen_rtx_REG (SImode
, TA_REGNUM
));
3662 SET_HARD_REG_BIT (clobbered_regs
, TA_REGNUM
);
3667 nds32_init_builtins (void)
3669 nds32_init_builtins_impl ();
3673 nds32_builtin_decl (unsigned code
, bool initialize_p
)
3675 /* Implement in nds32-intrinsic.c. */
3676 return nds32_builtin_decl_impl (code
, initialize_p
);
3680 nds32_expand_builtin (tree exp
,
3686 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
3690 /* ------------------------------------------------------------------------ */
3692 /* PART 4: Implemet extern function definitions,
3693 the prototype is in nds32-protos.h. */
3695 /* Run-time Target Specification. */
3698 nds32_cpu_cpp_builtins(struct cpp_reader
*pfile
)
3700 #define builtin_define(TXT) cpp_define (pfile, TXT)
3701 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
3702 builtin_define ("__nds32__");
3703 builtin_define ("__NDS32__");
3705 if (TARGET_HARD_FLOAT
)
3706 builtin_define ("__NDS32_ABI_2FP_PLUS__");
3708 builtin_define ("__NDS32_ABI_2__");
3711 builtin_define ("__NDS32_ISA_V2__");
3713 builtin_define ("__NDS32_ISA_V3__");
3715 builtin_define ("__NDS32_ISA_V3M__");
3717 if (TARGET_FPU_SINGLE
)
3718 builtin_define ("__NDS32_EXT_FPU_SP__");
3719 if (TARGET_FPU_DOUBLE
)
3720 builtin_define ("__NDS32_EXT_FPU_DP__");
3722 if (TARGET_EXT_FPU_FMA
)
3723 builtin_define ("__NDS32_EXT_FPU_FMA__");
3724 if (NDS32_EXT_FPU_DOT_E
)
3725 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
3726 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
3728 switch (nds32_fp_regnum
)
3732 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
3736 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
3740 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
3744 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
3751 if (TARGET_BIG_ENDIAN
)
3752 builtin_define ("__NDS32_EB__");
3754 builtin_define ("__NDS32_EL__");
3756 if (TARGET_REDUCED_REGS
)
3757 builtin_define ("__NDS32_REDUCED_REGS__");
3759 builtin_define ("__NDS32_CMOV__");
3760 if (TARGET_EXT_PERF
)
3761 builtin_define ("__NDS32_EXT_PERF__");
3762 if (TARGET_EXT_PERF2
)
3763 builtin_define ("__NDS32_EXT_PERF2__");
3764 if (TARGET_EXT_STRING
)
3765 builtin_define ("__NDS32_EXT_STRING__");
3767 builtin_define ("__NDS32_16_BIT__");
3768 if (TARGET_GP_DIRECT
)
3769 builtin_define ("__NDS32_GP_DIRECT__");
3771 builtin_define ("__NDS32_VH__");
3773 if (TARGET_BIG_ENDIAN
)
3774 builtin_define ("__big_endian__");
3776 builtin_assert ("cpu=nds32");
3777 builtin_assert ("machine=nds32");
3779 if (TARGET_HARD_FLOAT
)
3780 builtin_define ("__NDS32_ABI_2FP_PLUS");
3782 builtin_define ("__NDS32_ABI_2");
3784 #undef builtin_define
3785 #undef builtin_assert
3789 /* Defining Data Structures for Per-function Information. */
3792 nds32_init_expanders (void)
3794 /* Arrange to initialize and mark the machine per-function status. */
3795 init_machine_status
= nds32_init_machine_status
;
3799 /* Register Usage. */
3801 /* -- Order of Allocation of Registers. */
3804 nds32_adjust_reg_alloc_order (void)
3806 const int nds32_reg_alloc_order
[] = REG_ALLOC_ORDER
;
3808 /* Copy the default register allocation order, which is designed
3809 to optimize for code size. */
3810 memcpy(reg_alloc_order
, nds32_reg_alloc_order
, sizeof (reg_alloc_order
));
3812 /* Adjust few register allocation order when optimizing for speed. */
3815 memcpy (reg_alloc_order
, nds32_reg_alloc_order_for_speed
,
3816 sizeof (nds32_reg_alloc_order_for_speed
));
3820 /* -- How Values Fit in Registers. */
3823 nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED
,
3826 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
3829 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3832 nds32_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
3834 if (regno
> FIRST_PSEUDO_REGISTER
)
3837 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
) && NDS32_IS_FPR_REGNUM (regno
))
3839 if (NDS32_IS_EXT_FPR_REGNUM(regno
))
3840 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno
) && (mode
== DFmode
));
3841 else if (mode
== SFmode
|| mode
== SImode
)
3842 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno
);
3843 else if (mode
== DFmode
)
3844 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
);
3849 /* Restrict double-word quantities to even register pairs. */
3850 if (regno
<= NDS32_LAST_GPR_REGNUM
)
3851 return (targetm
.hard_regno_nregs (regno
, mode
) == 1
3857 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
3858 tie QI/HI/SI modes together. */
3861 nds32_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3863 if ((GET_MODE_CLASS (mode1
) == MODE_INT
3864 && GET_MODE_CLASS (mode2
) == MODE_INT
)
3865 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
3866 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
)
3869 if (GET_MODE_SIZE (mode1
) == GET_MODE_SIZE (mode2
))
3871 if ((TARGET_FPU_SINGLE
&& !TARGET_FPU_DOUBLE
)
3872 && (mode1
== DFmode
|| mode2
== DFmode
))
3881 /* Register Classes. */
3884 nds32_regno_reg_class (int regno
)
3886 /* Refer to nds32.h for more register class details. */
3888 if (regno
>= 0 && regno
<= 7)
3890 else if (regno
>= 8 && regno
<= 11)
3892 else if (regno
>= 12 && regno
<= 14)
3894 else if (regno
== 15)
3896 else if (regno
>= 16 && regno
<= 19)
3898 else if (regno
>= 20 && regno
<= 31)
3900 else if (regno
== 32 || regno
== 33)
3902 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
3903 know how to allocate register for $SFP and $AP, just tell IRA they
3904 are GENERAL_REGS, and ARM do this hack too. */
3905 return GENERAL_REGS
;
3907 else if (regno
>= 34 && regno
<= 97)
3914 /* Stack Layout and Calling Conventions. */
3916 /* -- Basic Stack Layout. */
3919 nds32_dynamic_chain_address (rtx frameaddr
)
3923 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
3924 We can access dynamic chain address from stack by [$fp - 12]. */
3925 return plus_constant (Pmode
, frameaddr
, -12);
3929 /* For general case we push $fp and $lp into stack at prologue.
3930 We can access dynamic chain address from stack by [$fp - 8]. */
3931 return plus_constant (Pmode
, frameaddr
, -8);
3936 nds32_return_addr_rtx (int count
,
3944 /* In nds32 ABI design, we can expect that $lp is always available
3945 from stack by [$fp - 4] location. */
3947 addr
= plus_constant (Pmode
, frameaddr
, offset
);
3948 addr
= memory_address (Pmode
, addr
);
3950 return gen_rtx_MEM (Pmode
, addr
);
3953 /* If count == 0, it means we are at current frame,
3954 the return address is $r30 ($lp). */
3955 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
3958 /* -- Eliminating Frame Pointer and Arg Pointer. */
3961 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
3963 HOST_WIDE_INT offset
;
3965 /* Compute and setup stack frame size.
3966 The result will be in cfun->machine. */
3967 nds32_compute_stack_frame ();
3969 /* Remember to consider
3970 cfun->machine->callee_saved_area_gpr_padding_bytes and
3971 cfun->machine->eh_return_data_regs_size
3972 when calculating offset. */
3973 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
3975 offset
= (cfun
->machine
->fp_size
3976 + cfun
->machine
->gp_size
3977 + cfun
->machine
->lp_size
3978 + cfun
->machine
->callee_saved_gpr_regs_size
3979 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
3980 + cfun
->machine
->callee_saved_fpr_regs_size
3981 + cfun
->machine
->eh_return_data_regs_size
3982 + cfun
->machine
->local_size
3983 + cfun
->machine
->out_args_size
);
3985 else if (from_reg
== ARG_POINTER_REGNUM
3986 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3990 else if (from_reg
== FRAME_POINTER_REGNUM
3991 && to_reg
== STACK_POINTER_REGNUM
)
3993 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
3995 else if (from_reg
== FRAME_POINTER_REGNUM
3996 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3998 offset
= (-1) * (cfun
->machine
->fp_size
3999 + cfun
->machine
->gp_size
4000 + cfun
->machine
->lp_size
4001 + cfun
->machine
->callee_saved_gpr_regs_size
4002 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4003 + cfun
->machine
->callee_saved_fpr_regs_size
4004 + cfun
->machine
->eh_return_data_regs_size
);
4014 /* -- Passing Arguments in Registers. */
4017 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4018 tree fntype ATTRIBUTE_UNUSED
,
4019 rtx libname ATTRIBUTE_UNUSED
,
4020 tree fndecl ATTRIBUTE_UNUSED
,
4021 int n_named_args ATTRIBUTE_UNUSED
)
4023 /* Initial available registers. The values are offset against
4024 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
4025 for passing arguments. */
4026 cum
->gpr_offset
= 0;
4027 cum
->fpr_offset
= 0;
4030 /* -- Function Entry and Exit. */
4032 /* Function for normal multiple push prologue. */
4034 nds32_expand_prologue (void)
4040 /* Compute and setup stack frame size.
4041 The result will be in cfun->machine. */
4042 nds32_compute_stack_frame ();
4044 /* If this is a variadic function, first we need to push argument
4045 registers that hold the unnamed argument value. */
4046 if (cfun
->machine
->va_args_size
!= 0)
4048 Rb
= cfun
->machine
->va_args_first_regno
;
4049 Re
= cfun
->machine
->va_args_last_regno
;
4050 /* No need to push $fp, $gp, or $lp. */
4051 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, true);
4053 /* We may also need to adjust stack pointer for padding bytes
4054 because varargs may cause $sp not 8-byte aligned. */
4055 if (cfun
->machine
->va_args_area_padding_bytes
)
4057 /* Generate sp adjustment instruction. */
4058 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
4060 nds32_emit_adjust_frame (stack_pointer_rtx
,
4066 /* If the function is 'naked',
4067 we do not have to generate prologue code fragment. */
4068 if (cfun
->machine
->naked_p
)
4071 /* Get callee_first_regno and callee_last_regno. */
4072 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4073 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4075 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4076 to be saved, we don't have to create multiple push instruction.
4077 Otherwise, a multiple push instruction is needed. */
4078 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4079 && cfun
->machine
->fp_size
== 0
4080 && cfun
->machine
->gp_size
== 0
4081 && cfun
->machine
->lp_size
== 0))
4083 /* Create multiple push instruction rtx. */
4084 nds32_emit_stack_push_multiple (
4086 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
,
4090 /* Save eh data registers. */
4091 if (cfun
->machine
->use_eh_return_p
)
4093 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4094 Re
= cfun
->machine
->eh_return_data_last_regno
;
4096 /* No need to push $fp, $gp, or $lp.
4097 Also, this is not variadic arguments push. */
4098 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, false);
4101 /* Check frame_pointer_needed to see
4102 if we shall emit fp adjustment instruction. */
4103 if (frame_pointer_needed
)
4105 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
4106 + (4 * callee-saved-registers)
4107 + (4 * exception-handling-data-registers)
4108 Note: No need to adjust
4109 cfun->machine->callee_saved_area_gpr_padding_bytes,
4110 because, at this point, stack pointer is just
4111 at the position after push instruction. */
4112 fp_adjust
= cfun
->machine
->fp_size
4113 + cfun
->machine
->gp_size
4114 + cfun
->machine
->lp_size
4115 + cfun
->machine
->callee_saved_gpr_regs_size
4116 + cfun
->machine
->eh_return_data_regs_size
;
4118 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4123 /* Save fpu registers. */
4124 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4126 /* When $sp moved to bottom of stack, we need to check whether
4127 the range of offset in the FPU instruction. */
4128 int fpr_offset
= cfun
->machine
->local_size
4129 + cfun
->machine
->out_args_size
4130 + cfun
->machine
->callee_saved_fpr_regs_size
;
4132 /* Check FPU instruction offset imm14s. */
4133 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset
)))
4135 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4136 + cfun
->machine
->callee_saved_fpr_regs_size
;
4138 /* Save fpu registers, need to allocate stack space
4139 for fpu callee registers. And now $sp position
4140 on callee saved fpr registers. */
4141 nds32_emit_adjust_frame (stack_pointer_rtx
,
4145 /* Emit fpu store instruction, using [$sp + offset] store
4147 nds32_emit_push_fpr_callee_saved (0);
4149 /* Adjust $sp = $sp - local_size - out_args_size. */
4150 sp_adjust
= cfun
->machine
->local_size
4151 + cfun
->machine
->out_args_size
;
4153 /* Allocate stack space for local size and out args size. */
4154 nds32_emit_adjust_frame (stack_pointer_rtx
,
4160 /* Offset range in Is14, so $sp moved to bottom of stack. */
4162 /* Adjust $sp = $sp - local_size - out_args_size
4163 - callee_saved_area_gpr_padding_bytes
4164 - callee_saved_fpr_regs_size. */
4165 sp_adjust
= cfun
->machine
->local_size
4166 + cfun
->machine
->out_args_size
4167 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4168 + cfun
->machine
->callee_saved_fpr_regs_size
;
4170 nds32_emit_adjust_frame (stack_pointer_rtx
,
4174 /* Emit fpu store instruction, using [$sp + offset] store
4176 int fpr_position
= cfun
->machine
->out_args_size
4177 + cfun
->machine
->local_size
;
4178 nds32_emit_push_fpr_callee_saved (fpr_position
);
4183 /* Adjust $sp = $sp - local_size - out_args_size
4184 - callee_saved_area_gpr_padding_bytes. */
4185 sp_adjust
= cfun
->machine
->local_size
4186 + cfun
->machine
->out_args_size
4187 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4189 /* sp_adjust value may be out of range of the addi instruction,
4190 create alternative add behavior with TA_REGNUM if necessary,
4191 using NEGATIVE value to tell that we are decreasing address. */
4192 nds32_emit_adjust_frame (stack_pointer_rtx
,
4197 /* Prevent the instruction scheduler from
4198 moving instructions across the boundary. */
4199 emit_insn (gen_blockage ());
4202 /* Function for normal multiple pop epilogue. */
4204 nds32_expand_epilogue (bool sibcall_p
)
4209 /* Compute and setup stack frame size.
4210 The result will be in cfun->machine. */
4211 nds32_compute_stack_frame ();
4213 /* Prevent the instruction scheduler from
4214 moving instructions across the boundary. */
4215 emit_insn (gen_blockage ());
4217 /* If the function is 'naked', we do not have to generate
4218 epilogue code fragment BUT 'ret' instruction.
4219 However, if this function is also a variadic function,
4220 we need to create adjust stack pointer before 'ret' instruction. */
4221 if (cfun
->machine
->naked_p
)
4223 /* If this is a variadic function, we do not have to restore argument
4224 registers but need to adjust stack pointer back to previous stack
4225 frame location before return. */
4226 if (cfun
->machine
->va_args_size
!= 0)
4228 /* Generate sp adjustment instruction.
4229 We need to consider padding bytes here. */
4230 sp_adjust
= cfun
->machine
->va_args_size
4231 + cfun
->machine
->va_args_area_padding_bytes
;
4233 nds32_emit_adjust_frame (stack_pointer_rtx
,
4238 /* Generate return instruction by using 'return_internal' pattern.
4239 Make sure this instruction is after gen_blockage(). */
4241 emit_jump_insn (gen_return_internal ());
4245 if (frame_pointer_needed
)
4247 /* Restore fpu registers. */
4248 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4250 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4252 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4253 - (4 * callee-saved-registers)
4254 - (4 * exception-handling-data-registers)
4255 - (4 * callee-saved-gpr-registers padding byte)
4256 - (4 * callee-saved-fpr-registers)
4257 Note: we want to adjust stack pointer
4258 to the position for callee-saved fpr register,
4259 And restore fpu register use .bi instruction to adjust $sp
4260 from callee-saved fpr register to pop instruction. */
4261 sp_adjust
= cfun
->machine
->fp_size
4262 + cfun
->machine
->gp_size
4263 + cfun
->machine
->lp_size
4264 + cfun
->machine
->callee_saved_gpr_regs_size
4265 + cfun
->machine
->eh_return_data_regs_size
4266 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4267 + cfun
->machine
->callee_saved_fpr_regs_size
;
4269 nds32_emit_adjust_frame (stack_pointer_rtx
,
4270 hard_frame_pointer_rtx
,
4273 /* Emit fpu load instruction, using .bi instruction
4274 load fpu registers. */
4275 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4279 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4280 - (4 * callee-saved-registers)
4281 - (4 * exception-handling-data-registers)
4282 Note: No need to adjust
4283 cfun->machine->callee_saved_area_gpr_padding_bytes,
4284 because we want to adjust stack pointer
4285 to the position for pop instruction. */
4286 sp_adjust
= cfun
->machine
->fp_size
4287 + cfun
->machine
->gp_size
4288 + cfun
->machine
->lp_size
4289 + cfun
->machine
->callee_saved_gpr_regs_size
4290 + cfun
->machine
->eh_return_data_regs_size
;
4292 nds32_emit_adjust_frame (stack_pointer_rtx
,
4293 hard_frame_pointer_rtx
,
4299 /* Restore fpu registers. */
4300 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4302 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4304 /* Adjust $sp = $sp + local_size + out_args_size. */
4305 sp_adjust
= cfun
->machine
->local_size
4306 + cfun
->machine
->out_args_size
;
4308 nds32_emit_adjust_frame (stack_pointer_rtx
,
4312 /* Emit fpu load instruction, using .bi instruction
4313 load fpu registers, and adjust $sp from callee-saved fpr register
4314 to callee-saved gpr register. */
4315 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4319 /* If frame pointer is NOT needed,
4320 we cannot calculate the sp adjustment from frame pointer.
4321 Instead, we calculate the adjustment by local_size,
4322 out_args_size, and callee_saved_area_gpr_padding_bytes.
4323 Notice that such sp adjustment value may be out of range,
4324 so we have to deal with it as well. */
4326 /* Adjust $sp = $sp + local_size + out_args_size
4327 + callee_saved_area_gpr_padding_bytes. */
4328 sp_adjust
= cfun
->machine
->local_size
4329 + cfun
->machine
->out_args_size
4330 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4332 nds32_emit_adjust_frame (stack_pointer_rtx
,
4338 /* Restore eh data registers. */
4339 if (cfun
->machine
->use_eh_return_p
)
4341 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4342 Re
= cfun
->machine
->eh_return_data_last_regno
;
4344 /* No need to pop $fp, $gp, or $lp. */
4345 nds32_emit_stack_pop_multiple (Rb
, Re
, false, false, false);
4348 /* Get callee_first_regno and callee_last_regno. */
4349 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4350 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4352 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4353 to be saved, we don't have to create multiple pop instruction.
4354 Otherwise, a multiple pop instruction is needed. */
4355 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4356 && cfun
->machine
->fp_size
== 0
4357 && cfun
->machine
->gp_size
== 0
4358 && cfun
->machine
->lp_size
== 0))
4360 /* Create multiple pop instruction rtx. */
4361 nds32_emit_stack_pop_multiple (
4363 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
);
4366 /* If this is a variadic function, we do not have to restore argument
4367 registers but need to adjust stack pointer back to previous stack
4368 frame location before return. */
4369 if (cfun
->machine
->va_args_size
!= 0)
4371 /* Generate sp adjustment instruction.
4372 We need to consider padding bytes here. */
4373 sp_adjust
= cfun
->machine
->va_args_size
4374 + cfun
->machine
->va_args_area_padding_bytes
;
4376 nds32_emit_adjust_frame (stack_pointer_rtx
,
4381 /* If this function uses __builtin_eh_return, make stack adjustment
4382 for exception handler. */
4383 if (cfun
->machine
->use_eh_return_p
)
4385 /* We need to unwind the stack by the offset computed by
4386 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4387 based on SP. Ideally we would update the SP and define the
4388 CFA along the lines of:
4390 SP = SP + EH_RETURN_STACKADJ_RTX
4391 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4393 However the dwarf emitter only understands a constant
4396 The solution chosen here is to use the otherwise $ta ($r15)
4397 as a temporary register to hold the current SP value. The
4398 CFA is described using $ta then SP is modified. */
4403 ta_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
4405 insn
= emit_move_insn (ta_reg
, stack_pointer_rtx
);
4406 add_reg_note (insn
, REG_CFA_DEF_CFA
, ta_reg
);
4407 RTX_FRAME_RELATED_P (insn
) = 1;
4409 emit_insn (gen_addsi3 (stack_pointer_rtx
,
4411 EH_RETURN_STACKADJ_RTX
));
4413 /* Ensure the assignment to $ta does not get optimized away. */
4417 /* Generate return instruction. */
4419 emit_jump_insn (gen_return_internal ());
4422 /* Function for v3push prologue. */
4424 nds32_expand_prologue_v3push (void)
4431 /* Compute and setup stack frame size.
4432 The result will be in cfun->machine. */
4433 nds32_compute_stack_frame ();
4435 if (cfun
->machine
->callee_saved_gpr_regs_size
> 0)
4436 df_set_regs_ever_live (FP_REGNUM
, 1);
4438 /* If the function is 'naked',
4439 we do not have to generate prologue code fragment. */
4440 if (cfun
->machine
->naked_p
)
4443 /* Get callee_first_regno and callee_last_regno. */
4444 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4445 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4447 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
4448 where imm8u has to be 8-byte alignment. */
4449 sp_adjust
= cfun
->machine
->local_size
4450 + cfun
->machine
->out_args_size
4451 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4452 + cfun
->machine
->callee_saved_fpr_regs_size
;
4454 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4455 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
4457 /* We can use 'push25 Re,imm8u'. */
4459 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4460 the pattern 'stack_v3push' is implemented in nds32.md. */
4461 nds32_emit_stack_v3push (Rb
, Re
, sp_adjust
);
4463 /* Save fpu registers. */
4464 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4466 /* Calculate fpr position. */
4467 int fpr_position
= cfun
->machine
->local_size
4468 + cfun
->machine
->out_args_size
;
4469 /* Emit fpu store instruction, using [$sp + offset] store
4471 nds32_emit_push_fpr_callee_saved (fpr_position
);
4474 /* Check frame_pointer_needed to see
4475 if we shall emit fp adjustment instruction. */
4476 if (frame_pointer_needed
)
4478 /* adjust $fp = $sp + 4 ($fp size)
4481 + (4 * n) (callee-saved registers)
4482 + sp_adjust ('push25 Re,imm8u')
4483 Note: Since we use 'push25 Re,imm8u',
4484 the position of stack pointer is further
4485 changed after push instruction.
4486 Hence, we need to take sp_adjust value
4487 into consideration. */
4488 fp_adjust
= cfun
->machine
->fp_size
4489 + cfun
->machine
->gp_size
4490 + cfun
->machine
->lp_size
4491 + cfun
->machine
->callee_saved_gpr_regs_size
4494 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4501 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4503 /* Calculate fpr space. */
4504 fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4505 + cfun
->machine
->callee_saved_fpr_regs_size
;
4507 /* We have to use 'push25 Re, fpr_space', to pre-allocate
4508 callee saved fpr registers space. */
4509 nds32_emit_stack_v3push (Rb
, Re
, fpr_space
);
4510 nds32_emit_push_fpr_callee_saved (0);
4514 /* We have to use 'push25 Re,0' and
4515 expand one more instruction to adjust $sp later. */
4517 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4518 the pattern 'stack_v3push' is implemented in nds32.md. */
4519 nds32_emit_stack_v3push (Rb
, Re
, 0);
4522 /* Check frame_pointer_needed to see
4523 if we shall emit fp adjustment instruction. */
4524 if (frame_pointer_needed
)
4526 /* adjust $fp = $sp + 4 ($fp size)
4529 + (4 * n) (callee-saved registers)
4530 Note: Since we use 'push25 Re,0',
4531 the stack pointer is just at the position
4532 after push instruction.
4533 No need to take sp_adjust into consideration. */
4534 fp_adjust
= cfun
->machine
->fp_size
4535 + cfun
->machine
->gp_size
4536 + cfun
->machine
->lp_size
4537 + cfun
->machine
->callee_saved_gpr_regs_size
;
4539 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4541 /* We use 'push25 Re, fpr_space', the $sp is
4542 on callee saved fpr position, so need to consider
4544 fp_adjust
= fp_adjust
+ fpr_space
;
4547 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4552 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4554 /* We use 'push25 Re, fpr_space',
4555 the $sp is on callee saved fpr position,
4556 no need to consider fpr space. */
4557 sp_adjust
= sp_adjust
- fpr_space
;
4560 /* Because we use 'push25 Re,0',
4561 we need to expand one more instruction to adjust $sp.
4562 using NEGATIVE value to tell that we are decreasing address. */
4563 nds32_emit_adjust_frame (stack_pointer_rtx
,
4568 /* Prevent the instruction scheduler from
4569 moving instructions across the boundary. */
4570 emit_insn (gen_blockage ());
4573 /* Function for v3pop epilogue. */
4575 nds32_expand_epilogue_v3pop (bool sibcall_p
)
4580 /* Compute and setup stack frame size.
4581 The result will be in cfun->machine. */
4582 nds32_compute_stack_frame ();
4584 /* Prevent the instruction scheduler from
4585 moving instructions across the boundary. */
4586 emit_insn (gen_blockage ());
4588 /* If the function is 'naked', we do not have to generate
4589 epilogue code fragment BUT 'ret' instruction. */
4590 if (cfun
->machine
->naked_p
)
4592 /* Generate return instruction by using 'return_internal' pattern.
4593 Make sure this instruction is after gen_blockage(). */
4595 emit_jump_insn (gen_return_internal ());
4599 /* Get callee_first_regno and callee_last_regno. */
4600 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4601 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4603 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
4604 where imm8u has to be 8-byte alignment. */
4605 sp_adjust
= cfun
->machine
->local_size
4606 + cfun
->machine
->out_args_size
4607 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4608 + cfun
->machine
->callee_saved_fpr_regs_size
;
4610 /* We have to consider alloca issue as well.
4611 If the function does call alloca(), the stack pointer is not fixed.
4612 In that case, we cannot use 'pop25 Re,imm8u' directly.
4613 We have to caculate stack pointer from frame pointer
4614 and then use 'pop25 Re,0'.
4615 Of course, the frame_pointer_needed should be nonzero
4616 if the function calls alloca(). */
4617 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4618 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4619 && !cfun
->calls_alloca
)
4621 /* Restore fpu registers. */
4622 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4624 int fpr_position
= cfun
->machine
->local_size
4625 + cfun
->machine
->out_args_size
;
4626 /* Emit fpu load instruction, using [$sp + offset] restore
4628 nds32_emit_v3pop_fpr_callee_saved (fpr_position
);
4631 /* We can use 'pop25 Re,imm8u'. */
4633 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4634 the pattern 'stack_v3pop' is implementad in nds32.md. */
4635 nds32_emit_stack_v3pop (Rb
, Re
, sp_adjust
);
4639 /* We have to use 'pop25 Re,0', and prior to it,
4640 we must expand one more instruction to adjust $sp. */
4642 if (frame_pointer_needed
)
4644 /* adjust $sp = $fp - 4 ($fp size)
4647 - (4 * n) (callee-saved registers)
4648 Note: No need to adjust
4649 cfun->machine->callee_saved_area_gpr_padding_bytes,
4650 because we want to adjust stack pointer
4651 to the position for pop instruction. */
4652 sp_adjust
= cfun
->machine
->fp_size
4653 + cfun
->machine
->gp_size
4654 + cfun
->machine
->lp_size
4655 + cfun
->machine
->callee_saved_gpr_regs_size
;
4657 /* Restore fpu registers. */
4658 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4660 /* Set $sp to callee saved fpr position, we need to restore
4662 sp_adjust
= sp_adjust
4663 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4664 + cfun
->machine
->callee_saved_fpr_regs_size
;
4666 nds32_emit_adjust_frame (stack_pointer_rtx
,
4667 hard_frame_pointer_rtx
,
4670 /* Emit fpu load instruction, using [$sp + offset] restore
4672 nds32_emit_v3pop_fpr_callee_saved (0);
4676 nds32_emit_adjust_frame (stack_pointer_rtx
,
4677 hard_frame_pointer_rtx
,
4683 /* If frame pointer is NOT needed,
4684 we cannot calculate the sp adjustment from frame pointer.
4685 Instead, we calculate the adjustment by local_size,
4686 out_args_size, and callee_saved_area_padding_bytes.
4687 Notice that such sp adjustment value may be out of range,
4688 so we have to deal with it as well. */
4690 /* Adjust $sp = $sp + local_size + out_args_size
4691 + callee_saved_area_gpr_padding_bytes
4692 + callee_saved_fpr_regs_size. */
4693 sp_adjust
= cfun
->machine
->local_size
4694 + cfun
->machine
->out_args_size
4695 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4696 + cfun
->machine
->callee_saved_fpr_regs_size
;
4698 /* Restore fpu registers. */
4699 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4701 /* Set $sp to callee saved fpr position, we need to restore
4703 sp_adjust
= sp_adjust
4704 - cfun
->machine
->callee_saved_area_gpr_padding_bytes
4705 - cfun
->machine
->callee_saved_fpr_regs_size
;
4707 nds32_emit_adjust_frame (stack_pointer_rtx
,
4711 /* Emit fpu load instruction, using [$sp + offset] restore
4713 nds32_emit_v3pop_fpr_callee_saved (0);
4717 /* sp_adjust value may be out of range of the addi instruction,
4718 create alternative add behavior with TA_REGNUM if necessary,
4719 using POSITIVE value to tell that we are increasing
4721 nds32_emit_adjust_frame (stack_pointer_rtx
,
4727 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4729 /* We have fpr need to restore, so $sp is set on callee saved fpr
4730 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
4731 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4732 + cfun
->machine
->callee_saved_fpr_regs_size
;
4733 nds32_emit_stack_v3pop (Rb
, Re
, fpr_space
);
4737 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4738 the pattern 'stack_v3pop' is implementad in nds32.md. */
4739 nds32_emit_stack_v3pop (Rb
, Re
, 0);
4742 /* Generate return instruction. */
4743 emit_jump_insn (gen_pop25return ());
4746 /* Return nonzero if this function is known to have a null epilogue.
4747 This allows the optimizer to omit jumps to jumps if no stack
4750 nds32_can_use_return_insn (void)
4754 /* Prior to reloading, we can't tell how many registers must be saved.
4755 Thus we can not determine whether this function has null epilogue. */
4756 if (!reload_completed
)
4759 sp_adjust
= cfun
->machine
->local_size
4760 + cfun
->machine
->out_args_size
4761 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4762 + cfun
->machine
->callee_saved_fpr_regs_size
;
4763 if (!cfun
->machine
->fp_as_gp_p
4764 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4765 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4766 && !cfun
->calls_alloca
4767 && NDS32_V3PUSH_AVAILABLE_P
4768 && !(TARGET_HARD_FLOAT
4769 && (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)))
4772 /* If no stack was created, two conditions must be satisfied:
4773 1. This is a naked function.
4774 So there is no callee-saved, local size, or outgoing size.
4775 2. This is NOT a variadic function.
4776 So there is no pushing arguement registers into the stack. */
4777 return (cfun
->machine
->naked_p
&& (cfun
->machine
->va_args_size
== 0));
4781 nds32_case_vector_shorten_mode (int min_offset
, int max_offset
,
4782 rtx body ATTRIBUTE_UNUSED
)
4784 if (min_offset
< 0 || max_offset
>= 0x2000)
4788 /* The jump table maybe need to 2 byte alignment,
4789 so reserved 1 byte for check max_offset. */
4790 if (max_offset
>= 0xff)
4797 /* ------------------------------------------------------------------------ */
4799 /* Return alignment for the label. */
4801 nds32_target_alignment (rtx_insn
*label
)
4805 if (!NDS32_ALIGN_P ())
4808 insn
= next_active_insn (label
);
4810 /* Always align to 4 byte when first instruction after label is jump
4811 instruction since length for that might changed, so let's always align
4812 it for make sure we don't lose any perfomance here. */
4814 || (get_attr_length (insn
) == 2
4815 && !JUMP_P (insn
) && !CALL_P (insn
)))
4821 /* Return alignment for data. */
4823 nds32_data_alignment (tree data
,
4824 unsigned int basic_align
)
4826 if ((basic_align
< BITS_PER_WORD
)
4827 && (TREE_CODE (data
) == ARRAY_TYPE
4828 || TREE_CODE (data
) == UNION_TYPE
4829 || TREE_CODE (data
) == RECORD_TYPE
))
4830 return BITS_PER_WORD
;
4835 /* Return alignment for constant value. */
4836 static HOST_WIDE_INT
4837 nds32_constant_alignment (const_tree constant
,
4838 HOST_WIDE_INT basic_align
)
4840 /* Make string literal and constant for constructor to word align. */
4841 if (((TREE_CODE (constant
) == STRING_CST
4842 || TREE_CODE (constant
) == CONSTRUCTOR
4843 || TREE_CODE (constant
) == UNION_TYPE
4844 || TREE_CODE (constant
) == RECORD_TYPE
4845 || TREE_CODE (constant
) == ARRAY_TYPE
)
4846 && basic_align
< BITS_PER_WORD
))
4847 return BITS_PER_WORD
;
4852 /* Return alignment for local variable. */
4854 nds32_local_alignment (tree local ATTRIBUTE_UNUSED
,
4855 unsigned int basic_align
)
4857 bool at_least_align_to_word
= false;
4858 /* Make local array, struct and union at least align to word for make
4859 sure it can unroll memcpy when initialize by constant. */
4860 switch (TREE_CODE (local
))
4865 at_least_align_to_word
= true;
4868 at_least_align_to_word
= false;
4871 if (at_least_align_to_word
4872 && (basic_align
< BITS_PER_WORD
))
4873 return BITS_PER_WORD
;
4879 nds32_split_double_word_load_store_p(rtx
*operands
, bool load_p
)
4881 rtx mem
= load_p
? operands
[1] : operands
[0];
4882 /* Do split at split2 if -O0 or schedule 2 not enable. */
4883 if (optimize
== 0 || !flag_schedule_insns_after_reload
)
4884 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4886 /* Split double word load store after copy propgation. */
4887 if (current_pass
== NULL
)
4890 const char *pass_name
= current_pass
->name
;
4891 if (pass_name
&& ((strcmp (pass_name
, "split4") == 0)
4892 || (strcmp (pass_name
, "split5") == 0)))
4893 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4899 nds32_use_blocks_for_constant_p (machine_mode mode
,
4900 const_rtx x ATTRIBUTE_UNUSED
)
4902 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
4903 && (mode
== DFmode
|| mode
== SFmode
))
4909 /* ------------------------------------------------------------------------ */
4911 /* PART 5: Initialize target hook structure and definitions. */
4913 /* Controlling the Compilation Driver. */
4916 /* Run-time Target Specification. */
4919 /* Defining Data Structures for Per-function Information. */
4922 /* Storage Layout. */
4924 #undef TARGET_PROMOTE_FUNCTION_MODE
4925 #define TARGET_PROMOTE_FUNCTION_MODE \
4926 default_promote_function_mode_always_promote
4928 #undef TARGET_EXPAND_TO_RTL_HOOK
4929 #define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
4931 #undef TARGET_CONSTANT_ALIGNMENT
4932 #define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment
4935 /* Layout of Source Language Data Types. */
4938 /* Register Usage. */
4940 /* -- Basic Characteristics of Registers. */
4942 #undef TARGET_CONDITIONAL_REGISTER_USAGE
4943 #define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
4945 /* -- Order of Allocation of Registers. */
4947 /* -- How Values Fit in Registers. */
4949 #undef TARGET_HARD_REGNO_NREGS
4950 #define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
4952 #undef TARGET_HARD_REGNO_MODE_OK
4953 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
4955 #undef TARGET_MODES_TIEABLE_P
4956 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
4958 /* -- Handling Leaf Functions. */
4960 /* -- Registers That Form a Stack. */
4963 /* Register Classes. */
4965 #undef TARGET_CLASS_MAX_NREGS
4966 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
4968 #undef TARGET_REGISTER_PRIORITY
4969 #define TARGET_REGISTER_PRIORITY nds32_register_priority
4971 #undef TARGET_CAN_CHANGE_MODE_CLASS
4972 #define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
4975 /* Obsolete Macros for Defining Constraints. */
4978 /* Stack Layout and Calling Conventions. */
4980 /* -- Basic Stack Layout. */
4982 /* -- Exception Handling Support. */
4984 /* -- Specifying How Stack Checking is Done. */
4986 /* -- Registers That Address the Stack Frame. */
4988 /* -- Eliminating Frame Pointer and Arg Pointer. */
4990 #undef TARGET_CAN_ELIMINATE
4991 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
4993 /* -- Passing Function Arguments on the Stack. */
4995 /* -- Passing Arguments in Registers. */
4997 #undef TARGET_FUNCTION_ARG
4998 #define TARGET_FUNCTION_ARG nds32_function_arg
5000 #undef TARGET_MUST_PASS_IN_STACK
5001 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
5003 #undef TARGET_ARG_PARTIAL_BYTES
5004 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
5006 #undef TARGET_FUNCTION_ARG_ADVANCE
5007 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5009 #undef TARGET_FUNCTION_ARG_BOUNDARY
5010 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5012 /* -- How Scalar Function Values Are Returned. */
5014 #undef TARGET_FUNCTION_VALUE
5015 #define TARGET_FUNCTION_VALUE nds32_function_value
5017 #undef TARGET_LIBCALL_VALUE
5018 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5020 #undef TARGET_FUNCTION_VALUE_REGNO_P
5021 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5023 /* -- How Large Values Are Returned. */
5025 #undef TARGET_RETURN_IN_MEMORY
5026 #define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
5028 /* -- Caller-Saves Register Allocation. */
5030 /* -- Function Entry and Exit. */
5032 #undef TARGET_ASM_FUNCTION_PROLOGUE
5033 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5035 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5036 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5038 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5039 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5041 #undef TARGET_ASM_FUNCTION_EPILOGUE
5042 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5044 #undef TARGET_ASM_OUTPUT_MI_THUNK
5045 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5047 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5048 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5050 /* -- Generating Code for Profiling. */
5052 /* -- Permitting tail calls. */
5054 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5055 #define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
5057 #undef TARGET_WARN_FUNC_RETURN
5058 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5060 /* Stack smashing protection. */
5063 /* Implementing the Varargs Macros. */
5065 #undef TARGET_SETUP_INCOMING_VARARGS
5066 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5068 #undef TARGET_STRICT_ARGUMENT_NAMING
5069 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5072 /* Trampolines for Nested Functions. */
5074 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5075 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5077 #undef TARGET_TRAMPOLINE_INIT
5078 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5081 /* Implicit Calls to Library Routines. */
5084 /* Addressing Modes. */
5086 #undef TARGET_LEGITIMATE_ADDRESS_P
5087 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5090 /* Anchored Addresses. */
5093 /* Condition Code Status. */
5095 /* -- Representation of condition codes using (cc0). */
5097 /* -- Representation of condition codes using registers. */
5099 #undef TARGET_CANONICALIZE_COMPARISON
5100 #define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5102 /* -- Macros to control conditional execution. */
5105 /* Describing Relative Costs of Operations. */
5107 #undef TARGET_REGISTER_MOVE_COST
5108 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5110 #undef TARGET_MEMORY_MOVE_COST
5111 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5113 #undef TARGET_RTX_COSTS
5114 #define TARGET_RTX_COSTS nds32_rtx_costs
5116 #undef TARGET_ADDRESS_COST
5117 #define TARGET_ADDRESS_COST nds32_address_cost
5120 /* Adjusting the Instruction Scheduler. */
5123 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5125 #undef TARGET_ENCODE_SECTION_INFO
5126 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5129 /* Position Independent Code. */
5132 /* Defining the Output Assembler Language. */
5134 /* -- The Overall Framework of an Assembler File. */
5136 #undef TARGET_ASM_FILE_START
5137 #define TARGET_ASM_FILE_START nds32_asm_file_start
5138 #undef TARGET_ASM_FILE_END
5139 #define TARGET_ASM_FILE_END nds32_asm_file_end
5141 /* -- Output of Data. */
5143 #undef TARGET_ASM_ALIGNED_HI_OP
5144 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5146 #undef TARGET_ASM_ALIGNED_SI_OP
5147 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5149 /* -- Output of Uninitialized Variables. */
5151 /* -- Output and Generation of Labels. */
5153 #undef TARGET_ASM_GLOBALIZE_LABEL
5154 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5156 /* -- How Initialization Functions Are Handled. */
5158 /* -- Macros Controlling Initialization Routines. */
5160 /* -- Output of Assembler Instructions. */
5162 #undef TARGET_PRINT_OPERAND
5163 #define TARGET_PRINT_OPERAND nds32_print_operand
5164 #undef TARGET_PRINT_OPERAND_ADDRESS
5165 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5167 /* -- Output of Dispatch Tables. */
5169 /* -- Assembler Commands for Exception Regions. */
5171 #undef TARGET_DWARF_REGISTER_SPAN
5172 #define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5174 /* -- Assembler Commands for Alignment. */
5177 /* Controlling Debugging Information Format. */
5179 /* -- Macros Affecting All Debugging Formats. */
5181 /* -- Specific Options for DBX Output. */
5183 /* -- Open-Ended Hooks for DBX Format. */
5185 /* -- File Names in DBX Format. */
5187 /* -- Macros for DWARF Output. */
5189 /* -- Macros for VMS Debug Format. */
5192 /* Cross Compilation and Floating Point. */
5195 /* Mode Switching Instructions. */
5198 /* Defining target-specific uses of __attribute__. */
5200 #undef TARGET_ATTRIBUTE_TABLE
5201 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5203 #undef TARGET_MERGE_DECL_ATTRIBUTES
5204 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5206 #undef TARGET_INSERT_ATTRIBUTES
5207 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5209 #undef TARGET_OPTION_PRAGMA_PARSE
5210 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5212 #undef TARGET_OPTION_OVERRIDE
5213 #define TARGET_OPTION_OVERRIDE nds32_option_override
5216 /* Emulating TLS. */
5219 /* Defining coprocessor specifics for MIPS targets. */
5222 /* Parameters for Precompiled Header Validity Checking. */
5225 /* C++ ABI parameters. */
5228 /* Adding support for named address spaces. */
5231 /* Miscellaneous Parameters. */
5233 #undef TARGET_MD_ASM_ADJUST
5234 #define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5236 #undef TARGET_INIT_BUILTINS
5237 #define TARGET_INIT_BUILTINS nds32_init_builtins
5239 #undef TARGET_BUILTIN_DECL
5240 #define TARGET_BUILTIN_DECL nds32_builtin_decl
5242 #undef TARGET_EXPAND_BUILTIN
5243 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5246 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5247 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5250 /* ------------------------------------------------------------------------ */
5252 /* Initialize the GCC target structure. */
5254 struct gcc_target targetm
= TARGET_INITIALIZER
;
5256 /* ------------------------------------------------------------------------ */