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 attribute is used to tell this function to be ROM patch. */
321 { "indirect_call",0, 0, false, false, false, false, NULL
, NULL
},
323 /* The last attribute spec is set to be NULL. */
324 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
328 /* ------------------------------------------------------------------------ */
330 /* PART 2: Auxiliary static function definitions. */
332 /* Function to save and restore machine-specific function data. */
333 static struct machine_function
*
334 nds32_init_machine_status (void)
336 struct machine_function
*machine
;
337 machine
= ggc_cleared_alloc
<machine_function
> ();
339 /* Initially assume this function does not use __builtin_eh_return. */
340 machine
->use_eh_return_p
= 0;
342 /* Initially assume this function needs prologue/epilogue. */
343 machine
->naked_p
= 0;
345 /* Initially assume this function does NOT use fp_as_gp optimization. */
346 machine
->fp_as_gp_p
= 0;
348 /* Initially this function is not under strictly aligned situation. */
349 machine
->strict_aligned_p
= 0;
354 /* Function to compute stack frame size and
355 store into cfun->machine structure. */
357 nds32_compute_stack_frame (void)
363 /* Because nds32_compute_stack_frame() will be called from different place,
364 everytime we enter this function, we have to assume this function
365 needs prologue/epilogue. */
366 cfun
->machine
->naked_p
= 0;
369 /* If __builtin_eh_return is used, we better have frame pointer needed
370 so that we can easily locate the stack slot of return address. */
371 if (crtl
->calls_eh_return
)
373 frame_pointer_needed
= 1;
375 /* We need to mark eh data registers that need to be saved
377 cfun
->machine
->eh_return_data_first_regno
= EH_RETURN_DATA_REGNO (0);
378 for (r
= 0; EH_RETURN_DATA_REGNO (r
) != INVALID_REGNUM
; r
++)
379 cfun
->machine
->eh_return_data_last_regno
= r
;
381 cfun
->machine
->eh_return_data_regs_size
382 = 4 * (cfun
->machine
->eh_return_data_last_regno
383 - cfun
->machine
->eh_return_data_first_regno
385 cfun
->machine
->use_eh_return_p
= 1;
389 /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we
390 do not need to handle __builtin_eh_return case in this function. */
391 cfun
->machine
->eh_return_data_first_regno
= SP_REGNUM
;
392 cfun
->machine
->eh_return_data_last_regno
= SP_REGNUM
;
394 cfun
->machine
->eh_return_data_regs_size
= 0;
395 cfun
->machine
->use_eh_return_p
= 0;
398 /* Get variadic arguments size to prepare pretend arguments and
399 we will push them into stack at prologue by ourself. */
400 cfun
->machine
->va_args_size
= crtl
->args
.pretend_args_size
;
401 if (cfun
->machine
->va_args_size
!= 0)
403 cfun
->machine
->va_args_first_regno
404 = NDS32_GPR_ARG_FIRST_REGNUM
405 + NDS32_MAX_GPR_REGS_FOR_ARGS
406 - (crtl
->args
.pretend_args_size
/ UNITS_PER_WORD
);
407 cfun
->machine
->va_args_last_regno
408 = NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
- 1;
412 cfun
->machine
->va_args_first_regno
= SP_REGNUM
;
413 cfun
->machine
->va_args_last_regno
= SP_REGNUM
;
416 /* Important: We need to make sure that varargs area is 8-byte alignment. */
417 block_size
= cfun
->machine
->va_args_size
;
418 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
420 cfun
->machine
->va_args_area_padding_bytes
421 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
424 /* Get local variables, incoming variables, and temporary variables size.
425 Note that we need to make sure it is 8-byte alignment because
426 there may be no padding bytes if we are using LRA. */
427 cfun
->machine
->local_size
= NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
429 /* Get outgoing arguments size. */
430 cfun
->machine
->out_args_size
= crtl
->outgoing_args_size
;
432 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
433 Check whether $fp is ever live. */
434 cfun
->machine
->fp_size
= (df_regs_ever_live_p (FP_REGNUM
)) ? 4 : 0;
436 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
437 Check whether we are using PIC code genration. */
438 cfun
->machine
->gp_size
=
439 (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
)) ? 4 : 0;
441 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
442 Check whether $lp is ever live. */
443 cfun
->machine
->lp_size
444 = (flag_always_save_lp
|| df_regs_ever_live_p (LP_REGNUM
)) ? 4 : 0;
446 /* Initially there is no padding bytes. */
447 cfun
->machine
->callee_saved_area_gpr_padding_bytes
= 0;
449 /* Calculate the bytes of saving callee-saved registers on stack. */
450 cfun
->machine
->callee_saved_gpr_regs_size
= 0;
451 cfun
->machine
->callee_saved_first_gpr_regno
= SP_REGNUM
;
452 cfun
->machine
->callee_saved_last_gpr_regno
= SP_REGNUM
;
453 cfun
->machine
->callee_saved_fpr_regs_size
= 0;
454 cfun
->machine
->callee_saved_first_fpr_regno
= SP_REGNUM
;
455 cfun
->machine
->callee_saved_last_fpr_regno
= SP_REGNUM
;
457 /* Currently, there is no need to check $r28~$r31
458 because we will save them in another way. */
459 for (r
= 0; r
< 28; r
++)
461 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
463 /* Mark the first required callee-saved register
464 (only need to set it once).
465 If first regno == SP_REGNUM, we can tell that
466 it is the first time to be here. */
467 if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
468 cfun
->machine
->callee_saved_first_gpr_regno
= r
;
469 /* Mark the last required callee-saved register. */
470 cfun
->machine
->callee_saved_last_gpr_regno
= r
;
474 /* Recording fpu callee-saved register. */
475 if (TARGET_HARD_FLOAT
)
477 for (r
= NDS32_FIRST_FPR_REGNUM
; r
< NDS32_LAST_FPR_REGNUM
; r
++)
479 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
481 /* Mark the first required callee-saved register. */
482 if (cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
)
484 /* Make first callee-saved number is even,
485 bacause we use doubleword access, and this way
486 promise 8-byte alignemt. */
487 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r
))
488 cfun
->machine
->callee_saved_first_fpr_regno
= r
- 1;
490 cfun
->machine
->callee_saved_first_fpr_regno
= r
;
492 cfun
->machine
->callee_saved_last_fpr_regno
= r
;
496 /* Make last callee-saved register number is odd,
497 we hope callee-saved register is even. */
498 int last_fpr
= cfun
->machine
->callee_saved_last_fpr_regno
;
499 if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr
))
500 cfun
->machine
->callee_saved_last_fpr_regno
++;
503 /* Check if this function can omit prologue/epilogue code fragment.
504 If there is 'naked' attribute in this function,
505 we can set 'naked_p' flag to indicate that
506 we do not have to generate prologue/epilogue.
507 Or, if all the following conditions succeed,
508 we can set this function 'naked_p' as well:
509 condition 1: first_regno == last_regno == SP_REGNUM,
510 which means we do not have to save
511 any callee-saved registers.
512 condition 2: Both $lp and $fp are NOT live in this function,
513 which means we do not need to save them and there
515 condition 3: There is no local_size, which means
516 we do not need to adjust $sp. */
517 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
))
518 || (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
519 && cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
520 && cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
521 && cfun
->machine
->callee_saved_last_fpr_regno
== SP_REGNUM
522 && !df_regs_ever_live_p (FP_REGNUM
)
523 && !df_regs_ever_live_p (LP_REGNUM
)
524 && cfun
->machine
->local_size
== 0
527 /* Set this function 'naked_p' and other functions can check this flag.
528 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
529 callee-saved, local size, and outgoing size.
530 The varargs space and ret instruction may still present in
531 the prologue/epilogue expanding. */
532 cfun
->machine
->naked_p
= 1;
534 /* No need to save $fp, $gp, and $lp.
535 We should set these value to be zero
536 so that nds32_initial_elimination_offset() can work properly. */
537 cfun
->machine
->fp_size
= 0;
538 cfun
->machine
->gp_size
= 0;
539 cfun
->machine
->lp_size
= 0;
541 /* If stack usage computation is required,
542 we need to provide the static stack size. */
543 if (flag_stack_usage_info
)
544 current_function_static_stack_size
= 0;
546 /* No need to do following adjustment, return immediately. */
550 v3pushpop_p
= NDS32_V3PUSH_AVAILABLE_P
;
552 /* Adjustment for v3push instructions:
553 If we are using v3push (push25/pop25) instructions,
554 we need to make sure Rb is $r6 and Re is
555 located on $r6, $r8, $r10, or $r14.
556 Some results above will be discarded and recomputed.
557 Note that it is only available under V3/V3M ISA and we
558 DO NOT setup following stuff for isr or variadic function. */
562 cfun->machine->fp_size
563 cfun->machine->gp_size
564 cfun->machine->lp_size
565 cfun->machine->callee_saved_first_gpr_regno
566 cfun->machine->callee_saved_last_gpr_regno */
568 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
569 cfun
->machine
->fp_size
= 4;
570 cfun
->machine
->gp_size
= 4;
571 cfun
->machine
->lp_size
= 4;
573 /* Remember to set Rb = $r6. */
574 cfun
->machine
->callee_saved_first_gpr_regno
= 6;
576 if (cfun
->machine
->callee_saved_last_gpr_regno
<= 6)
579 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
581 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 8)
584 cfun
->machine
->callee_saved_last_gpr_regno
= 8;
586 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 10)
589 cfun
->machine
->callee_saved_last_gpr_regno
= 10;
591 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 14)
594 cfun
->machine
->callee_saved_last_gpr_regno
= 14;
596 else if (cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
)
598 /* If last_regno is SP_REGNUM, which means
599 it is never changed, so set it to Re = $r6. */
600 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
604 /* The program flow should not go here. */
609 int sp_adjust
= cfun
->machine
->local_size
610 + cfun
->machine
->out_args_size
611 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
612 + cfun
->machine
->callee_saved_fpr_regs_size
;
616 && !frame_pointer_needed
)
618 block_size
= cfun
->machine
->fp_size
619 + cfun
->machine
->gp_size
620 + cfun
->machine
->lp_size
;
622 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
623 block_size
+= (4 * (cfun
->machine
->callee_saved_last_gpr_regno
624 - cfun
->machine
->callee_saved_first_gpr_regno
627 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
629 /* $r14 is last callee save register. */
630 if (cfun
->machine
->callee_saved_last_gpr_regno
631 < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM
)
633 cfun
->machine
->callee_saved_last_gpr_regno
++;
635 else if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
637 cfun
->machine
->callee_saved_first_gpr_regno
638 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
639 cfun
->machine
->callee_saved_last_gpr_regno
640 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
645 /* We have correctly set callee_saved_first_gpr_regno
646 and callee_saved_last_gpr_regno.
647 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
648 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
649 we can update callee_saved_gpr_regs_size with new size. */
650 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
652 /* Compute pushed size of callee-saved registers. */
653 cfun
->machine
->callee_saved_gpr_regs_size
654 = 4 * (cfun
->machine
->callee_saved_last_gpr_regno
655 - cfun
->machine
->callee_saved_first_gpr_regno
659 if (TARGET_HARD_FLOAT
)
661 /* Compute size of callee svaed floating-point registers. */
662 if (cfun
->machine
->callee_saved_last_fpr_regno
!= SP_REGNUM
)
664 cfun
->machine
->callee_saved_fpr_regs_size
665 = 4 * (cfun
->machine
->callee_saved_last_fpr_regno
666 - cfun
->machine
->callee_saved_first_fpr_regno
671 /* Important: We need to make sure that
672 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
674 If it is not, calculate the padding bytes. */
675 block_size
= cfun
->machine
->fp_size
676 + cfun
->machine
->gp_size
677 + cfun
->machine
->lp_size
678 + cfun
->machine
->callee_saved_gpr_regs_size
;
679 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
681 cfun
->machine
->callee_saved_area_gpr_padding_bytes
682 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
685 /* If stack usage computation is required,
686 we need to provide the static stack size. */
687 if (flag_stack_usage_info
)
689 current_function_static_stack_size
690 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
)
691 + cfun
->machine
->local_size
692 + cfun
->machine
->out_args_size
;
696 /* Function to create a parallel rtx pattern
697 which presents stack push multiple behavior.
698 The overall concept are:
699 "push registers to memory",
700 "adjust stack pointer". */
702 nds32_emit_stack_push_multiple (unsigned Rb
, unsigned Re
,
703 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
,
719 /* We need to provide a customized rtx which contains
720 necessary information for data analysis,
721 so we create a parallel rtx like this:
722 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
724 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
727 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
729 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
731 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
733 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
735 (set (reg:SI SP_REGNUM)
736 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
738 /* Calculate the number of registers that will be pushed. */
746 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
747 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
748 num_use_regs
= extra_count
;
750 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
752 /* In addition to used registers,
753 we need one more space for (set sp sp-x) rtx. */
754 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
755 rtvec_alloc (num_use_regs
+ 1));
758 /* Initialize offset and start to create push behavior. */
759 offset
= -(num_use_regs
* 4);
761 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
762 for (regno
= Rb
; regno
<= Re
; regno
++)
764 /* Rb and Re may be SP_REGNUM.
765 We need to break this loop immediately. */
766 if (regno
== SP_REGNUM
)
769 reg
= gen_rtx_REG (SImode
, regno
);
770 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
773 push_rtx
= gen_rtx_SET (mem
, reg
);
774 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
775 RTX_FRAME_RELATED_P (push_rtx
) = 1;
780 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
783 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
784 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
787 push_rtx
= gen_rtx_SET (mem
, reg
);
788 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
789 RTX_FRAME_RELATED_P (push_rtx
) = 1;
795 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
796 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
799 push_rtx
= gen_rtx_SET (mem
, reg
);
800 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
801 RTX_FRAME_RELATED_P (push_rtx
) = 1;
807 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
808 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
811 push_rtx
= gen_rtx_SET (mem
, reg
);
812 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
813 RTX_FRAME_RELATED_P (push_rtx
) = 1;
818 /* Create (set sp sp-x). */
820 /* We need to re-calculate the offset value again for adjustment. */
821 offset
= -(num_use_regs
* 4);
823 = gen_rtx_SET (stack_pointer_rtx
,
824 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
825 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
826 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
828 parallel_insn
= emit_insn (parallel_insn
);
830 /* The insn rtx 'parallel_insn' will change frame layout.
831 We need to use RTX_FRAME_RELATED_P so that GCC is able to
832 generate CFI (Call Frame Information) stuff. */
833 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
835 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
836 since we will not restore those register at epilogue. */
839 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
840 copy_rtx (adjust_sp_rtx
), NULL_RTX
);
841 REG_NOTES (parallel_insn
) = dwarf
;
845 /* Function to create a parallel rtx pattern
846 which presents stack pop multiple behavior.
847 The overall concept are:
848 "pop registers from memory",
849 "adjust stack pointer". */
851 nds32_emit_stack_pop_multiple (unsigned Rb
, unsigned Re
,
852 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
)
865 rtx dwarf
= NULL_RTX
;
867 /* We need to provide a customized rtx which contains
868 necessary information for data analysis,
869 so we create a parallel rtx like this:
870 (parallel [(set (reg:SI Rb)
871 (mem (reg:SI SP_REGNUM)))
873 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
876 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
877 (set (reg:SI FP_REGNUM)
878 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
879 (set (reg:SI GP_REGNUM)
880 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
881 (set (reg:SI LP_REGNUM)
882 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
883 (set (reg:SI SP_REGNUM)
884 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
886 /* Calculate the number of registers that will be poped. */
894 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
895 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
896 num_use_regs
= extra_count
;
898 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
900 /* In addition to used registers,
901 we need one more space for (set sp sp+x) rtx. */
902 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
903 rtvec_alloc (num_use_regs
+ 1));
906 /* Initialize offset and start to create pop behavior. */
909 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
910 for (regno
= Rb
; regno
<= Re
; regno
++)
912 /* Rb and Re may be SP_REGNUM.
913 We need to break this loop immediately. */
914 if (regno
== SP_REGNUM
)
917 reg
= gen_rtx_REG (SImode
, regno
);
918 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
921 pop_rtx
= gen_rtx_SET (reg
, mem
);
922 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
923 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
927 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
930 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
933 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
934 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
937 pop_rtx
= gen_rtx_SET (reg
, mem
);
938 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
939 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
943 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
947 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
948 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
951 pop_rtx
= gen_rtx_SET (reg
, mem
);
952 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
953 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
957 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
961 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
962 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
965 pop_rtx
= gen_rtx_SET (reg
, mem
);
966 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
967 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
971 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
974 /* Create (set sp sp+x). */
976 /* The offset value is already in place. No need to re-calculate it. */
978 = gen_rtx_SET (stack_pointer_rtx
,
979 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
980 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
982 /* Tell gcc we adjust SP in this insn. */
983 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
985 parallel_insn
= emit_insn (parallel_insn
);
987 /* The insn rtx 'parallel_insn' will change frame layout.
988 We need to use RTX_FRAME_RELATED_P so that GCC is able to
989 generate CFI (Call Frame Information) stuff. */
990 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
992 /* Add CFI info by manual. */
993 REG_NOTES (parallel_insn
) = dwarf
;
996 /* Function to create a parallel rtx pattern
997 which presents stack v3push behavior.
998 The overall concept are:
999 "push registers to memory",
1000 "adjust stack pointer". */
1002 nds32_emit_stack_v3push (unsigned Rb
,
1017 /* We need to provide a customized rtx which contains
1018 necessary information for data analysis,
1019 so we create a parallel rtx like this:
1020 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
1022 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
1025 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
1027 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
1029 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
1031 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
1033 (set (reg:SI SP_REGNUM)
1034 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
1036 /* Calculate the number of registers that will be pushed.
1037 Since $fp, $gp, and $lp is always pushed with v3push instruction,
1038 we need to count these three registers.
1039 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1040 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1041 num_use_regs
= Re
- Rb
+ 1 + 3;
1043 /* In addition to used registers,
1044 we need one more space for (set sp sp-x-imm8u) rtx. */
1045 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1046 rtvec_alloc (num_use_regs
+ 1));
1049 /* Initialize offset and start to create push behavior. */
1050 offset
= -(num_use_regs
* 4);
1052 /* Create (set mem regX) from Rb, Rb+1 up to Re.
1053 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1054 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1055 for (regno
= Rb
; regno
<= Re
; regno
++)
1057 reg
= gen_rtx_REG (SImode
, regno
);
1058 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1061 push_rtx
= gen_rtx_SET (mem
, reg
);
1062 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1063 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1064 offset
= offset
+ 4;
1068 /* Create (set mem fp). */
1069 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1070 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1073 push_rtx
= gen_rtx_SET (mem
, reg
);
1074 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1075 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1076 offset
= offset
+ 4;
1078 /* Create (set mem gp). */
1079 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1080 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1083 push_rtx
= gen_rtx_SET (mem
, reg
);
1084 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1085 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1086 offset
= offset
+ 4;
1088 /* Create (set mem lp). */
1089 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1090 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1093 push_rtx
= gen_rtx_SET (mem
, reg
);
1094 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1095 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1096 offset
= offset
+ 4;
1099 /* Create (set sp sp-x-imm8u). */
1101 /* We need to re-calculate the offset value again for adjustment. */
1102 offset
= -(num_use_regs
* 4);
1104 = gen_rtx_SET (stack_pointer_rtx
,
1105 plus_constant (Pmode
,
1108 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1109 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
1111 parallel_insn
= emit_insn (parallel_insn
);
1113 /* The insn rtx 'parallel_insn' will change frame layout.
1114 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1115 generate CFI (Call Frame Information) stuff. */
1116 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1119 /* Function to create a parallel rtx pattern
1120 which presents stack v3pop behavior.
1121 The overall concept are:
1122 "pop registers from memory",
1123 "adjust stack pointer". */
1125 nds32_emit_stack_v3pop (unsigned Rb
,
1139 rtx dwarf
= NULL_RTX
;
1141 /* We need to provide a customized rtx which contains
1142 necessary information for data analysis,
1143 so we create a parallel rtx like this:
1144 (parallel [(set (reg:SI Rb)
1145 (mem (reg:SI SP_REGNUM)))
1147 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
1150 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
1151 (set (reg:SI FP_REGNUM)
1152 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
1153 (set (reg:SI GP_REGNUM)
1154 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
1155 (set (reg:SI LP_REGNUM)
1156 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
1157 (set (reg:SI SP_REGNUM)
1158 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
1160 /* Calculate the number of registers that will be poped.
1161 Since $fp, $gp, and $lp is always poped with v3pop instruction,
1162 we need to count these three registers.
1163 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1164 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1165 num_use_regs
= Re
- Rb
+ 1 + 3;
1167 /* In addition to used registers,
1168 we need one more space for (set sp sp+x+imm8u) rtx. */
1169 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1170 rtvec_alloc (num_use_regs
+ 1));
1173 /* Initialize offset and start to create pop behavior. */
1176 /* Create (set regX mem) from Rb, Rb+1 up to Re.
1177 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1178 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1179 for (regno
= Rb
; regno
<= Re
; regno
++)
1181 reg
= gen_rtx_REG (SImode
, regno
);
1182 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1185 pop_rtx
= gen_rtx_SET (reg
, mem
);
1186 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1187 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1188 offset
= offset
+ 4;
1191 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1194 /* Create (set fp mem). */
1195 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1196 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1199 pop_rtx
= gen_rtx_SET (reg
, mem
);
1200 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1201 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1202 offset
= offset
+ 4;
1204 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1206 /* Create (set gp mem). */
1207 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1208 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1211 pop_rtx
= gen_rtx_SET (reg
, mem
);
1212 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1213 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1214 offset
= offset
+ 4;
1216 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1218 /* Create (set lp mem ). */
1219 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1220 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1223 pop_rtx
= gen_rtx_SET (reg
, mem
);
1224 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1225 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1226 offset
= offset
+ 4;
1228 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1230 /* Create (set sp sp+x+imm8u). */
1232 /* The offset value is already in place. No need to re-calculate it. */
1234 = gen_rtx_SET (stack_pointer_rtx
,
1235 plus_constant (Pmode
,
1238 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1240 if (frame_pointer_needed
)
1242 /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp)
1244 mean reset frame pointer to $sp and reset to offset 0. */
1245 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
1247 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
1251 /* Tell gcc we adjust SP in this insn. */
1252 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
1253 copy_rtx (adjust_sp_rtx
), dwarf
);
1256 parallel_insn
= emit_insn (parallel_insn
);
1258 /* The insn rtx 'parallel_insn' will change frame layout.
1259 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1260 generate CFI (Call Frame Information) stuff. */
1261 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1263 /* Add CFI info by manual. */
1264 REG_NOTES (parallel_insn
) = dwarf
;
1268 nds32_emit_load_gp (void)
1270 rtx got_symbol
, pat
;
1272 /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
1273 emit_insn (gen_blockage ());
1275 got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
1276 /* sethi $gp, _GLOBAL_OFFSET_TABLE_ -8 */
1277 pat
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, got_symbol
), UNSPEC_GOTINIT
);
1278 pat
= gen_rtx_CONST (SImode
, gen_rtx_PLUS (Pmode
, pat
, GEN_INT (-8)));
1279 emit_insn (gen_sethi (pic_offset_table_rtx
,pat
));
1281 /* ori $gp, $gp, _GLOBAL_OFFSET_TABLE_ -4 */
1282 pat
= gen_rtx_UNSPEC (SImode
, gen_rtvec (1, got_symbol
), UNSPEC_GOTINIT
);
1283 pat
= gen_rtx_CONST (SImode
, gen_rtx_PLUS (Pmode
, pat
, GEN_INT (-4)));
1284 emit_insn (gen_lo_sum (pic_offset_table_rtx
, pic_offset_table_rtx
, pat
));
1287 emit_insn (gen_add_pc (pic_offset_table_rtx
, pic_offset_table_rtx
));
1289 /* Initial GLOBAL OFFSET TABLE don't do the scheduling. */
1290 emit_insn (gen_blockage ());
1293 /* Function that may creates more instructions
1294 for large value on adjusting stack pointer.
1296 In nds32 target, 'addi' can be used for stack pointer
1297 adjustment in prologue/epilogue stage.
1298 However, sometimes there are too many local variables so that
1299 the adjustment value is not able to be fit in the 'addi' instruction.
1300 One solution is to move value into a register
1301 and then use 'add' instruction.
1302 In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */
1304 nds32_emit_adjust_frame (rtx to_reg
, rtx from_reg
, int adjust_value
)
1307 rtx frame_adjust_insn
;
1308 rtx adjust_value_rtx
= GEN_INT (adjust_value
);
1310 if (adjust_value
== 0)
1313 if (!satisfies_constraint_Is15 (adjust_value_rtx
))
1315 /* The value is not able to fit in single addi instruction.
1316 Create more instructions of moving value into a register
1317 and then add stack pointer with it. */
1319 /* $r15 is going to be temporary register to hold the value. */
1320 tmp_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
1322 /* Create one more instruction to move value
1323 into the temporary register. */
1324 emit_move_insn (tmp_reg
, adjust_value_rtx
);
1326 /* Create new 'add' rtx. */
1327 frame_adjust_insn
= gen_addsi3 (to_reg
,
1330 /* Emit rtx into insn list and receive its transformed insn rtx. */
1331 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1333 /* Because (tmp_reg <- full_value) may be split into two
1334 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1335 We need to construct another (sp <- sp + full_value)
1336 and then insert it into sp_adjust_insn's reg note to
1337 represent a frame related expression.
1338 GCC knows how to refer it and output debug information. */
1343 plus_rtx
= plus_constant (Pmode
, from_reg
, adjust_value
);
1344 set_rtx
= gen_rtx_SET (to_reg
, plus_rtx
);
1345 add_reg_note (frame_adjust_insn
, REG_FRAME_RELATED_EXPR
, set_rtx
);
1349 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
1350 frame_adjust_insn
= gen_addsi3 (to_reg
,
1353 /* Emit rtx into instructions list and receive INSN rtx form. */
1354 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1357 /* The insn rtx 'sp_adjust_insn' will change frame layout.
1358 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1359 generate CFI (Call Frame Information) stuff. */
1360 RTX_FRAME_RELATED_P (frame_adjust_insn
) = 1;
1363 /* Return true if MODE/TYPE need double word alignment. */
1365 nds32_needs_double_word_align (machine_mode mode
, const_tree type
)
1369 /* Pick up the alignment according to the mode or type. */
1370 align
= NDS32_MODE_TYPE_ALIGN (mode
, type
);
1372 return (align
> PARM_BOUNDARY
);
1375 /* Return true if FUNC is a naked function. */
1377 nds32_naked_function_p (tree func
)
1381 if (TREE_CODE (func
) != FUNCTION_DECL
)
1384 t
= lookup_attribute ("naked", DECL_ATTRIBUTES (func
));
1386 return (t
!= NULL_TREE
);
1389 /* Function that determine whether a load postincrement is a good thing to use
1390 for a given mode. */
1392 nds32_use_load_post_increment (machine_mode mode
)
1394 return (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE(E_DImode
));
1397 /* Function that check if 'X' is a valid address register.
1398 The variable 'STRICT' is very important to
1399 make decision for register number.
1402 => We are in reload pass or after reload pass.
1403 The register number should be strictly limited in general registers.
1406 => Before reload pass, we are free to use any register number. */
1408 nds32_address_register_rtx_p (rtx x
, bool strict
)
1412 if (GET_CODE (x
) != REG
)
1418 return REGNO_OK_FOR_BASE_P (regno
);
1423 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1425 OUTER_MODE : Machine mode of outer address rtx.
1426 INDEX : Check if this rtx is valid to be a index for address.
1427 STRICT : If it is true, we are in reload pass or after reload pass. */
1429 nds32_legitimate_index_p (machine_mode outer_mode
,
1437 switch (GET_CODE (index
))
1440 regno
= REGNO (index
);
1441 /* If we are in reload pass or after reload pass,
1442 we need to limit it to general register. */
1444 return REGNO_OK_FOR_INDEX_P (regno
);
1449 /* The alignment of the integer value is determined by 'outer_mode'. */
1450 switch (GET_MODE_SIZE (outer_mode
))
1453 /* Further check if the value is legal for the 'outer_mode'. */
1454 if (satisfies_constraint_Is15 (index
))
1459 /* Further check if the value is legal for the 'outer_mode'. */
1460 if (satisfies_constraint_Is16 (index
))
1462 /* If it is not under strictly aligned situation,
1463 we can return true without checking alignment. */
1464 if (!cfun
->machine
->strict_aligned_p
)
1466 /* Make sure address is half word alignment. */
1467 else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index
)))
1473 /* Further check if the value is legal for the 'outer_mode'. */
1474 if (satisfies_constraint_Is17 (index
))
1476 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1478 if (!satisfies_constraint_Is14 (index
))
1482 /* If it is not under strictly aligned situation,
1483 we can return true without checking alignment. */
1484 if (!cfun
->machine
->strict_aligned_p
)
1486 /* Make sure address is word alignment. */
1487 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1493 if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index
) + 4,
1496 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1498 if (!satisfies_constraint_Is14 (index
))
1502 /* If it is not under strictly aligned situation,
1503 we can return true without checking alignment. */
1504 if (!cfun
->machine
->strict_aligned_p
)
1506 /* Make sure address is word alignment.
1507 Currently we do not have 64-bit load/store yet,
1508 so we will use two 32-bit load/store instructions to do
1509 memory access and they are single word alignment. */
1510 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1522 op0
= XEXP (index
, 0);
1523 op1
= XEXP (index
, 1);
1525 if (REG_P (op0
) && CONST_INT_P (op1
))
1528 multiplier
= INTVAL (op1
);
1530 /* We only allow (mult reg const_int_1), (mult reg const_int_2),
1531 (mult reg const_int_4) or (mult reg const_int_8). */
1532 if (multiplier
!= 1 && multiplier
!= 2
1533 && multiplier
!= 4 && multiplier
!= 8)
1536 regno
= REGNO (op0
);
1537 /* Limit it in general registers if we are
1538 in reload pass or after reload pass. */
1540 return REGNO_OK_FOR_INDEX_P (regno
);
1548 op0
= XEXP (index
, 0);
1549 op1
= XEXP (index
, 1);
1551 if (REG_P (op0
) && CONST_INT_P (op1
))
1554 /* op1 is already the sv value for use to do left shift. */
1557 /* We only allow (ashift reg const_int_0)
1558 or (ashift reg const_int_1) or (ashift reg const_int_2) or
1559 (ashift reg const_int_3). */
1560 if (sv
!= 0 && sv
!= 1 && sv
!=2 && sv
!= 3)
1563 regno
= REGNO (op0
);
1564 /* Limit it in general registers if we are
1565 in reload pass or after reload pass. */
1567 return REGNO_OK_FOR_INDEX_P (regno
);
1580 nds32_register_pass (
1581 rtl_opt_pass
*(*make_pass_func
) (gcc::context
*),
1582 enum pass_positioning_ops pass_pos
,
1583 const char *ref_pass_name
)
1585 opt_pass
*new_opt_pass
= make_pass_func (g
);
1587 struct register_pass_info insert_pass
=
1589 new_opt_pass
, /* pass */
1590 ref_pass_name
, /* reference_pass_name */
1591 1, /* ref_pass_instance_number */
1592 pass_pos
/* po_op */
1595 register_pass (&insert_pass
);
1598 /* This function is called from nds32_option_override ().
1599 All new passes should be registered here. */
1601 nds32_register_passes (void)
1603 nds32_register_pass (
1604 make_pass_nds32_relax_opt
,
1605 PASS_POS_INSERT_AFTER
,
1609 /* ------------------------------------------------------------------------ */
1611 /* PART 3: Implement target hook stuff definitions. */
1614 /* Computing the Length of an Insn.
1615 Modifies the length assigned to instruction INSN.
1616 LEN is the initially computed length of the insn. */
1618 nds32_adjust_insn_length (rtx_insn
*insn
, int length
)
1620 int adjust_value
= 0;
1621 switch (recog_memoized (insn
))
1623 case CODE_FOR_call_internal
:
1624 case CODE_FOR_call_value_internal
:
1626 if (NDS32_ALIGN_P ())
1628 rtx_insn
*next_insn
= next_active_insn (insn
);
1629 if (next_insn
&& get_attr_length (next_insn
) != 2)
1632 /* We need insert a nop after a noretun function call
1633 to prevent software breakpoint corrupt the next function. */
1634 if (find_reg_note (insn
, REG_NORETURN
, NULL_RTX
))
1642 return length
+ adjust_value
;
1649 /* Storage Layout. */
1651 /* This function will be called just before expansion into rtl. */
1653 nds32_expand_to_rtl_hook (void)
1655 /* We need to set strictly aligned situation.
1656 After that, the memory address checking in nds32_legitimate_address_p()
1657 will take alignment offset into consideration so that it will not create
1658 unaligned [base + offset] access during the rtl optimization. */
1659 cfun
->machine
->strict_aligned_p
= 1;
1663 /* Register Usage. */
1666 nds32_conditional_register_usage (void)
1670 if (TARGET_HARD_FLOAT
)
1672 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1673 regno
<= NDS32_LAST_FPR_REGNUM
; regno
++)
1675 fixed_regs
[regno
] = 0;
1676 if (regno
< NDS32_FIRST_FPR_REGNUM
+ NDS32_MAX_FPR_REGS_FOR_ARGS
)
1677 call_used_regs
[regno
] = 1;
1678 else if (regno
>= NDS32_FIRST_FPR_REGNUM
+ 22
1679 && regno
< NDS32_FIRST_FPR_REGNUM
+ 48)
1680 call_used_regs
[regno
] = 1;
1682 call_used_regs
[regno
] = 0;
1685 else if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1687 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1688 regno
<= NDS32_LAST_FPR_REGNUM
;
1690 fixed_regs
[regno
] = 0;
1695 /* Register Classes. */
1697 static unsigned char
1698 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED
,
1701 /* Return the maximum number of consecutive registers
1702 needed to represent "mode" in a register of "rclass". */
1703 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
1707 nds32_register_priority (int hard_regno
)
1709 /* Encourage to use r0-r7 for LRA when optimize for size. */
1714 else if (hard_regno
< 16)
1716 else if (hard_regno
< 28)
1723 if (hard_regno
> 27)
1731 nds32_can_change_mode_class (machine_mode from
,
1735 /* Don't spill double-precision register to two singal-precision
1737 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1738 && GET_MODE_SIZE (from
) != GET_MODE_SIZE (to
))
1740 return !reg_classes_intersect_p (rclass
, FP_REGS
);
1747 /* Stack Layout and Calling Conventions. */
1749 /* There are three kinds of pointer concepts using in GCC compiler:
1751 frame pointer: A pointer to the first location of local variables.
1752 stack pointer: A pointer to the top of a stack frame.
1753 argument pointer: A pointer to the incoming arguments.
1755 In nds32 target calling convention, we are using 8-byte alignment.
1756 Besides, we would like to have each stack frame of a function includes:
1759 1. previous hard frame pointer
1761 3. callee-saved registers
1762 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1764 cfun->machine->callee_saved_area_padding_bytes)
1768 2. spilling location
1769 3. <padding bytes> (it will be calculated by GCC itself)
1770 4. incoming arguments
1771 5. <padding bytes> (it will be calculated by GCC itself)
1774 1. <padding bytes> (it will be calculated by GCC itself)
1775 2. outgoing arguments
1777 We 'wrap' these blocks together with
1778 hard frame pointer ($r28) and stack pointer ($r31).
1779 By applying the basic frame/stack/argument pointers concept,
1780 the layout of a stack frame shoule be like this:
1783 old stack pointer -> ----
1785 | | saved arguments for
1786 | | vararg functions
1788 hard frame pointer -> --
1789 & argument pointer | | \
1790 | | previous hardware frame pointer
1792 | | callee-saved registers
1797 | | and incoming arguments
1804 stack pointer -> ----
1806 $SFP and $AP are used to represent frame pointer and arguments pointer,
1807 which will be both eliminated as hard frame pointer. */
1809 /* -- Eliminating Frame Pointer and Arg Pointer. */
1812 nds32_can_eliminate (const int from_reg
, const int to_reg
)
1814 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1817 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1820 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1823 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1829 /* -- Passing Arguments in Registers. */
1832 nds32_function_arg (cumulative_args_t ca
, machine_mode mode
,
1833 const_tree type
, bool named
)
1836 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1838 /* The last time this hook is called,
1839 it is called with MODE == VOIDmode. */
1840 if (mode
== VOIDmode
)
1843 /* For nameless arguments, we need to take care it individually. */
1846 /* If we are under hard float abi, we have arguments passed on the
1847 stack and all situation can be handled by GCC itself. */
1848 if (TARGET_HARD_FLOAT
)
1851 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1853 /* If we still have enough registers to pass argument, pick up
1854 next available register number. */
1856 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1857 return gen_rtx_REG (mode
, regno
);
1860 /* No register available, return NULL_RTX.
1861 The compiler will use stack to pass argument instead. */
1865 /* The following is to handle named argument.
1866 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1868 if (TARGET_HARD_FLOAT
)
1870 /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR
1871 to pass argument. We have to further check TYPE and MODE so
1872 that we can determine which kind of register we shall use. */
1874 /* Note that we need to pass argument entirely in registers under
1876 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1877 && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum
->fpr_offset
, mode
, type
))
1879 /* Pick up the next available FPR register number. */
1881 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
);
1882 return gen_rtx_REG (mode
, regno
);
1884 else if (GET_MODE_CLASS (mode
) != MODE_FLOAT
1885 && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1887 /* Pick up the next available GPR register number. */
1889 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1890 return gen_rtx_REG (mode
, regno
);
1895 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1896 argument. Since we allow to pass argument partially in registers,
1897 we can just return it if there are still registers available. */
1898 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1900 /* Pick up the next available register number. */
1902 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1903 return gen_rtx_REG (mode
, regno
);
1908 /* No register available, return NULL_RTX.
1909 The compiler will use stack to pass argument instead. */
1914 nds32_must_pass_in_stack (machine_mode mode
, const_tree type
)
1916 /* Return true if a type must be passed in memory.
1917 If it is NOT using hard float abi, small aggregates can be
1918 passed in a register even we are calling a variadic function.
1919 So there is no need to take padding into consideration. */
1920 if (TARGET_HARD_FLOAT
)
1921 return must_pass_in_stack_var_size_or_pad (mode
, type
);
1923 return must_pass_in_stack_var_size (mode
, type
);
1927 nds32_arg_partial_bytes (cumulative_args_t ca
, machine_mode mode
,
1928 tree type
, bool named ATTRIBUTE_UNUSED
)
1930 /* Returns the number of bytes at the beginning of an argument that
1931 must be put in registers. The value must be zero for arguments that are
1932 passed entirely in registers or that are entirely pushed on the stack.
1933 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1934 first register to be used by the caller for this argument. */
1935 unsigned int needed_reg_count
;
1936 unsigned int remaining_reg_count
;
1937 CUMULATIVE_ARGS
*cum
;
1939 cum
= get_cumulative_args (ca
);
1941 /* Under hard float abi, we better have argument entirely passed in
1942 registers or pushed on the stack so that we can reduce the complexity
1943 of dealing with cum->gpr_offset and cum->fpr_offset. */
1944 if (TARGET_HARD_FLOAT
)
1947 /* If we have already runned out of argument registers, return zero
1948 so that the argument will be entirely pushed on the stack. */
1949 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1950 >= NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
)
1953 /* Calculate how many registers do we need for this argument. */
1954 needed_reg_count
= NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1956 /* Calculate how many argument registers have left for passing argument.
1957 Note that we should count it from next available register number. */
1959 = NDS32_MAX_GPR_REGS_FOR_ARGS
1960 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1961 - NDS32_GPR_ARG_FIRST_REGNUM
);
1963 /* Note that we have to return the nubmer of bytes, not registers count. */
1964 if (needed_reg_count
> remaining_reg_count
)
1965 return remaining_reg_count
* UNITS_PER_WORD
;
1971 nds32_function_arg_advance (cumulative_args_t ca
, machine_mode mode
,
1972 const_tree type
, bool named
)
1974 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1978 /* We need to further check TYPE and MODE so that we can determine
1979 which kind of register we shall advance. */
1981 /* Under hard float abi, we may advance FPR registers. */
1982 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1985 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
)
1986 - NDS32_FPR_ARG_FIRST_REGNUM
1987 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1992 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1993 - NDS32_GPR_ARG_FIRST_REGNUM
1994 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1999 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
2000 we can advance next register as well so that caller is
2001 able to pass arguments in registers and callee must be
2002 in charge of pushing all of them into stack. */
2003 if (!TARGET_HARD_FLOAT
)
2006 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
2007 - NDS32_GPR_ARG_FIRST_REGNUM
2008 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
2014 nds32_function_arg_boundary (machine_mode mode
, const_tree type
)
2016 return (nds32_needs_double_word_align (mode
, type
)
2017 ? NDS32_DOUBLE_WORD_ALIGNMENT
2022 nds32_vector_mode_supported_p (machine_mode mode
)
2024 if (mode
== V4QImode
2025 || mode
== V2HImode
)
2026 return NDS32_EXT_DSP_P ();
2031 /* -- How Scalar Function Values Are Returned. */
2034 nds32_function_value (const_tree ret_type
,
2035 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
2036 bool outgoing ATTRIBUTE_UNUSED
)
2041 mode
= TYPE_MODE (ret_type
);
2042 unsignedp
= TYPE_UNSIGNED (ret_type
);
2044 if (INTEGRAL_TYPE_P (ret_type
))
2045 mode
= promote_mode (ret_type
, mode
, &unsignedp
);
2047 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2048 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2050 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2054 nds32_libcall_value (machine_mode mode
,
2055 const_rtx fun ATTRIBUTE_UNUSED
)
2057 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2058 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2060 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2064 nds32_function_value_regno_p (const unsigned int regno
)
2066 if (regno
== NDS32_GPR_RET_FIRST_REGNUM
2067 || (TARGET_HARD_FLOAT
2068 && regno
== NDS32_FPR_RET_FIRST_REGNUM
))
2074 /* -- How Large Values Are Returned. */
2077 nds32_return_in_memory (const_tree type
,
2078 const_tree fntype ATTRIBUTE_UNUSED
)
2080 /* Note that int_size_in_bytes can return -1 if the size can vary
2081 or is larger than an integer. */
2082 HOST_WIDE_INT size
= int_size_in_bytes (type
);
2084 /* For COMPLEX_TYPE, if the total size cannot be hold within two registers,
2085 the return value is supposed to be in memory. We need to be aware of
2086 that the size may be -1. */
2087 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2088 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2091 /* If it is BLKmode and the total size cannot be hold within two registers,
2092 the return value is supposed to be in memory. We need to be aware of
2093 that the size may be -1. */
2094 if (TYPE_MODE (type
) == BLKmode
)
2095 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2098 /* For other cases, having result in memory is unnecessary. */
2102 /* -- Function Entry and Exit. */
2104 /* The content produced from this function
2105 will be placed before prologue body. */
2107 nds32_asm_function_prologue (FILE *file
)
2110 const char *func_name
;
2114 /* All stack frame information is supposed to be
2115 already computed when expanding prologue.
2116 The result is in cfun->machine.
2117 DO NOT call nds32_compute_stack_frame() here
2118 because it may corrupt the essential information. */
2120 fprintf (file
, "\t! BEGIN PROLOGUE\n");
2121 fprintf (file
, "\t! fp needed: %d\n", frame_pointer_needed
);
2122 fprintf (file
, "\t! pretend_args: %d\n", cfun
->machine
->va_args_size
);
2123 fprintf (file
, "\t! local_size: %d\n", cfun
->machine
->local_size
);
2124 fprintf (file
, "\t! out_args_size: %d\n", cfun
->machine
->out_args_size
);
2126 /* Use df_regs_ever_live_p() to detect if the register
2127 is ever used in the current function. */
2128 fprintf (file
, "\t! registers ever_live: ");
2129 for (r
= 0; r
< 65; r
++)
2131 if (df_regs_ever_live_p (r
))
2132 fprintf (file
, "%s, ", reg_names
[r
]);
2136 /* Display the attributes of this function. */
2137 fprintf (file
, "\t! function attributes: ");
2138 /* Get the attributes tree list.
2139 Note that GCC builds attributes list with reverse order. */
2140 attrs
= DECL_ATTRIBUTES (current_function_decl
);
2142 /* If there is no any attribute, print out "None". */
2144 fprintf (file
, "None");
2146 /* If there are some attributes, try if we need to
2147 construct isr vector information. */
2148 func_name
= IDENTIFIER_POINTER (DECL_NAME (current_function_decl
));
2149 nds32_construct_isr_vectors_information (attrs
, func_name
);
2151 /* Display all attributes of this function. */
2154 name
= TREE_PURPOSE (attrs
);
2155 fprintf (file
, "%s ", IDENTIFIER_POINTER (name
));
2157 /* Pick up the next attribute. */
2158 attrs
= TREE_CHAIN (attrs
);
2163 /* After rtl prologue has been expanded, this function is used. */
2165 nds32_asm_function_end_prologue (FILE *file
)
2167 fprintf (file
, "\t! END PROLOGUE\n");
2169 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2170 we can generate special directive: ".omit_fp_begin"
2171 to guide linker doing fp-as-gp optimization.
2172 However, for a naked function, which means
2173 it should not have prologue/epilogue,
2174 using fp-as-gp still requires saving $fp by push/pop behavior and
2175 there is no benefit to use fp-as-gp on such small function.
2176 So we need to make sure this function is NOT naked as well. */
2177 if (!frame_pointer_needed
2178 && !cfun
->machine
->naked_p
2179 && cfun
->machine
->fp_as_gp_p
)
2181 fprintf (file
, "\t! ----------------------------------------\n");
2182 fprintf (file
, "\t! Guide linker to do "
2183 "link time optimization: fp-as-gp\n");
2184 fprintf (file
, "\t! We add one more instruction to "
2185 "initialize $fp near to $gp location.\n");
2186 fprintf (file
, "\t! If linker fails to use fp-as-gp transformation,\n");
2187 fprintf (file
, "\t! this extra instruction should be "
2188 "eliminated at link stage.\n");
2189 fprintf (file
, "\t.omit_fp_begin\n");
2190 fprintf (file
, "\tla\t$fp,_FP_BASE_\n");
2191 fprintf (file
, "\t! ----------------------------------------\n");
2195 /* Before rtl epilogue has been expanded, this function is used. */
2197 nds32_asm_function_begin_epilogue (FILE *file
)
2199 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2200 we can generate special directive: ".omit_fp_end"
2201 to claim fp-as-gp optimization range.
2202 However, for a naked function,
2203 which means it should not have prologue/epilogue,
2204 using fp-as-gp still requires saving $fp by push/pop behavior and
2205 there is no benefit to use fp-as-gp on such small function.
2206 So we need to make sure this function is NOT naked as well. */
2207 if (!frame_pointer_needed
2208 && !cfun
->machine
->naked_p
2209 && cfun
->machine
->fp_as_gp_p
)
2211 fprintf (file
, "\t! ----------------------------------------\n");
2212 fprintf (file
, "\t! Claim the range of fp-as-gp "
2213 "link time optimization\n");
2214 fprintf (file
, "\t.omit_fp_end\n");
2215 fprintf (file
, "\t! ----------------------------------------\n");
2218 fprintf (file
, "\t! BEGIN EPILOGUE\n");
2221 /* The content produced from this function
2222 will be placed after epilogue body. */
2224 nds32_asm_function_epilogue (FILE *file
)
2226 fprintf (file
, "\t! END EPILOGUE\n");
2230 nds32_asm_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
2231 HOST_WIDE_INT delta
,
2232 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
2237 /* Make sure unwind info is emitted for the thunk if needed. */
2238 final_start_function (emit_barrier (), file
, 1);
2240 this_regno
= (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
)
2246 fprintf (file
, "\tsmw.adm\t$r31, [$r31], $r31, 4\n");
2247 fprintf (file
, "\tsethi\t%s, hi20(_GLOBAL_OFFSET_TABLE_-8)\n",
2248 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
2249 fprintf (file
, "\tori\t%s, %s, lo12(_GLOBAL_OFFSET_TABLE_-4)\n",
2250 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
2251 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
2254 fprintf (file
, "\tadd5.pc\t$gp\n");
2257 fprintf (file
, "\tmfusr\t$ta, $pc\n");
2258 fprintf (file
, "\tadd\t%s, $ta, %s\n",
2259 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
2260 reg_names
[PIC_OFFSET_TABLE_REGNUM
]);
2266 if (satisfies_constraint_Is15 (GEN_INT (delta
)))
2268 fprintf (file
, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC
"\n",
2269 this_regno
, this_regno
, delta
);
2271 else if (satisfies_constraint_Is20 (GEN_INT (delta
)))
2273 fprintf (file
, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC
"\n", delta
);
2274 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2279 "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC
")\n",
2282 "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC
")\n",
2284 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2290 fprintf (file
, "\tla\t$ta, ");
2291 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
2292 fprintf (file
, "@PLT\n");
2293 fprintf (file
, "\t! epilogue\n");
2294 fprintf (file
, "\tlwi.bi\t%s, [%s], 4\n",
2295 reg_names
[PIC_OFFSET_TABLE_REGNUM
],
2296 reg_names
[STACK_POINTER_REGNUM
]);
2297 fprintf (file
, "\tbr\t$ta\n");
2301 fprintf (file
, "\tb\t");
2302 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
2303 fprintf (file
, "\n");
2306 final_end_function ();
2309 /* -- Permitting tail calls. */
2311 /* Return true if it is ok to do sibling call optimization. */
2313 nds32_function_ok_for_sibcall (tree decl
,
2314 tree exp ATTRIBUTE_UNUSED
)
2316 /* The DECL is NULL if it is an indirect call. */
2318 /* 1. Do not apply sibling call if -mv3push is enabled,
2319 because pop25 instruction also represents return behavior.
2320 2. If this function is a variadic function, do not apply sibling call
2321 because the stack layout may be a mess.
2322 3. We don't want to apply sibling call optimization for indirect
2323 sibcall because the pop behavior in epilogue may pollute the
2324 content of caller-saved regsiter when the register is used for
2326 4. In pic mode, it may use some registers for PLT call. */
2327 return (!TARGET_V3PUSH
2328 && (cfun
->machine
->va_args_size
== 0)
2333 /* Determine whether we need to enable warning for function return check. */
2335 nds32_warn_func_return (tree decl
)
2337 /* Naked functions are implemented entirely in assembly, including the
2338 return sequence, so suppress warnings about this. */
2339 return !nds32_naked_function_p (decl
);
2343 /* Implementing the Varargs Macros. */
2346 nds32_setup_incoming_varargs (cumulative_args_t ca
,
2349 int *pretend_args_size
,
2350 int second_time ATTRIBUTE_UNUSED
)
2352 unsigned int total_args_regs
;
2353 unsigned int num_of_used_regs
;
2354 unsigned int remaining_reg_count
;
2355 CUMULATIVE_ARGS
*cum
;
2357 /* If we are under hard float abi, we do not need to set *pretend_args_size.
2358 So that all nameless arguments are pushed by caller and all situation
2359 can be handled by GCC itself. */
2360 if (TARGET_HARD_FLOAT
)
2363 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
2364 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
2365 However, for nameless(anonymous) arguments, we should push them on the
2366 stack so that all the nameless arguments appear to have been passed
2367 consecutively in the memory for accessing. Hence, we need to check and
2368 exclude the registers that are used for named arguments. */
2370 cum
= get_cumulative_args (ca
);
2372 /* The MODE and TYPE describe the last argument.
2373 We need those information to determine the remaining registers
2376 = NDS32_MAX_GPR_REGS_FOR_ARGS
+ NDS32_GPR_ARG_FIRST_REGNUM
;
2378 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
2379 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
2381 remaining_reg_count
= total_args_regs
- num_of_used_regs
;
2382 *pretend_args_size
= remaining_reg_count
* UNITS_PER_WORD
;
2388 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
2390 /* If this hook returns true, the named argument of FUNCTION_ARG is always
2391 true for named arguments, and false for unnamed arguments. */
2396 /* Trampolines for Nested Functions. */
2399 nds32_asm_trampoline_template (FILE *f
)
2401 if (TARGET_REDUCED_REGS
)
2403 /* Trampoline is not supported on reduced-set registers yet. */
2404 sorry ("a nested function is not supported for reduced registers");
2408 asm_fprintf (f
, "\t! Trampoline code template\n");
2409 asm_fprintf (f
, "\t! This code fragment will be copied "
2410 "into stack on demand\n");
2412 asm_fprintf (f
, "\tmfusr\t$r16,$pc\n");
2413 asm_fprintf (f
, "\tlwi\t$r15,[$r16 + 20] "
2414 "! load nested function address\n");
2415 asm_fprintf (f
, "\tlwi\t$r16,[$r16 + 16] "
2416 "! load chain_value\n");
2417 asm_fprintf (f
, "\tjr\t$r15\n");
2420 /* Preserve space ($pc + 16) for saving chain_value,
2421 nds32_trampoline_init will fill the value in this slot. */
2422 asm_fprintf (f
, "\t! space for saving chain_value\n");
2423 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2425 /* Preserve space ($pc + 20) for saving nested function address,
2426 nds32_trampoline_init will fill the value in this slot. */
2427 asm_fprintf (f
, "\t! space for saving nested function address\n");
2428 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2431 /* Emit RTL insns to initialize the variable parts of a trampoline. */
2433 nds32_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
2437 /* Nested function address. */
2439 /* The memory rtx that is going to
2440 be filled with chain_value. */
2441 rtx chain_value_mem
;
2442 /* The memory rtx that is going to
2443 be filled with nested function address. */
2444 rtx nested_func_mem
;
2446 /* Start address of trampoline code in stack, for doing cache sync. */
2447 rtx sync_cache_addr
;
2448 /* Temporary register for sync instruction. */
2450 /* Instruction-cache sync instruction,
2451 requesting an argument as starting address. */
2453 /* For convenience reason of doing comparison. */
2454 int tramp_align_in_bytes
;
2456 /* Trampoline is not supported on reduced-set registers yet. */
2457 if (TARGET_REDUCED_REGS
)
2458 sorry ("a nested function is not supported for reduced registers");
2460 /* STEP 1: Copy trampoline code template into stack,
2461 fill up essential data into stack. */
2463 /* Extract nested function address rtx. */
2464 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
2466 /* m_tramp is memory rtx that is going to be filled with trampoline code.
2467 We have nds32_asm_trampoline_template() to emit template pattern. */
2468 emit_block_move (m_tramp
, assemble_trampoline_template (),
2469 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
2471 /* After copying trampoline code into stack,
2472 fill chain_value into stack. */
2473 chain_value_mem
= adjust_address (m_tramp
, SImode
, 16);
2474 emit_move_insn (chain_value_mem
, chain_value
);
2475 /* After copying trampoline code int stack,
2476 fill nested function address into stack. */
2477 nested_func_mem
= adjust_address (m_tramp
, SImode
, 20);
2478 emit_move_insn (nested_func_mem
, fnaddr
);
2480 /* STEP 2: Sync instruction-cache. */
2482 /* We have successfully filled trampoline code into stack.
2483 However, in order to execute code in stack correctly,
2484 we must sync instruction cache. */
2485 sync_cache_addr
= XEXP (m_tramp
, 0);
2486 tmp_reg
= gen_reg_rtx (SImode
);
2487 isync_insn
= gen_unspec_volatile_isync (tmp_reg
);
2489 /* Because nds32_cache_block_size is in bytes,
2490 we get trampoline alignment in bytes for convenient comparison. */
2491 tramp_align_in_bytes
= TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
;
2493 if (tramp_align_in_bytes
>= nds32_cache_block_size
2494 && (tramp_align_in_bytes
% nds32_cache_block_size
) == 0)
2496 /* Under this condition, the starting address of trampoline
2497 must be aligned to the starting address of each cache block
2498 and we do not have to worry about cross-boundary issue. */
2500 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2501 / nds32_cache_block_size
;
2504 emit_move_insn (tmp_reg
,
2505 plus_constant (Pmode
, sync_cache_addr
,
2506 nds32_cache_block_size
* i
));
2507 emit_insn (isync_insn
);
2510 else if (TRAMPOLINE_SIZE
> nds32_cache_block_size
)
2512 /* The starting address of trampoline code
2513 may not be aligned to the cache block,
2514 so the trampoline code may be across two cache block.
2515 We need to sync the last element, which is 4-byte size,
2516 of trampoline template. */
2518 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2519 / nds32_cache_block_size
;
2522 emit_move_insn (tmp_reg
,
2523 plus_constant (Pmode
, sync_cache_addr
,
2524 nds32_cache_block_size
* i
));
2525 emit_insn (isync_insn
);
2528 /* The last element of trampoline template is 4-byte size. */
2529 emit_move_insn (tmp_reg
,
2530 plus_constant (Pmode
, sync_cache_addr
,
2531 TRAMPOLINE_SIZE
- 4));
2532 emit_insn (isync_insn
);
2536 /* This is the simplest case.
2537 Because TRAMPOLINE_SIZE is less than or
2538 equal to nds32_cache_block_size,
2539 we can just sync start address and
2540 the last element of trampoline code. */
2542 /* Sync starting address of tampoline code. */
2543 emit_move_insn (tmp_reg
, sync_cache_addr
);
2544 emit_insn (isync_insn
);
2545 /* Sync the last element, which is 4-byte size,
2546 of trampoline template. */
2547 emit_move_insn (tmp_reg
,
2548 plus_constant (Pmode
, sync_cache_addr
,
2549 TRAMPOLINE_SIZE
- 4));
2550 emit_insn (isync_insn
);
2553 /* Set instruction serialization barrier
2554 to guarantee the correct operations. */
2555 emit_insn (gen_unspec_volatile_isb ());
2559 /* Addressing Modes. */
2562 nds32_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
2564 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
2566 /* When using floating-point instructions,
2567 we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */
2568 if ((mode
== DFmode
|| mode
== SFmode
)
2569 && (GET_CODE (x
) == SYMBOL_REF
2570 || GET_CODE(x
) == CONST
))
2573 /* Allow [post_modify] addressing mode, when using FPU instructions. */
2574 if (GET_CODE (x
) == POST_MODIFY
2577 if (GET_CODE (XEXP (x
, 0)) == REG
2578 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2580 rtx plus_op
= XEXP (x
, 1);
2581 rtx op0
= XEXP (plus_op
, 0);
2582 rtx op1
= XEXP (plus_op
, 1);
2584 if (nds32_address_register_rtx_p (op0
, strict
)
2585 && CONST_INT_P (op1
))
2587 if (satisfies_constraint_Is14 (op1
))
2589 /* If it is not under strictly aligned situation,
2590 we can return true without checking alignment. */
2591 if (!cfun
->machine
->strict_aligned_p
)
2593 /* Make sure address is word alignment.
2594 Currently we do not have 64-bit load/store yet,
2595 so we will use two 32-bit load/store instructions to do
2596 memory access and they are single word alignment. */
2597 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1
)))
2605 /* For (mem:DI addr) or (mem:DF addr) case,
2606 we only allow 'addr' to be [reg], [symbol_ref],
2607 [const], or [reg + const_int] pattern. */
2608 if (mode
== DImode
|| mode
== DFmode
)
2610 /* Allow [Reg + const_int] addressing mode. */
2611 if (GET_CODE (x
) == PLUS
)
2613 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2614 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
)
2615 && CONST_INT_P (XEXP (x
, 1)))
2617 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2618 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
)
2619 && CONST_INT_P (XEXP (x
, 0)))
2623 /* Allow [post_inc] and [post_dec] addressing mode. */
2624 if (GET_CODE (x
) == POST_INC
|| GET_CODE (x
) == POST_DEC
)
2626 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2630 /* Now check [reg], [symbol_ref], and [const]. */
2631 if (GET_CODE (x
) != REG
2632 && GET_CODE (x
) != SYMBOL_REF
2633 && GET_CODE (x
) != CONST
)
2637 /* Check if 'x' is a valid address. */
2638 switch (GET_CODE (x
))
2641 /* (mem (reg A)) => [Ra] */
2642 return nds32_address_register_rtx_p (x
, strict
);
2645 /* (mem (symbol_ref A)) => [symbol_ref] */
2647 if (flag_pic
|| SYMBOL_REF_TLS_MODEL (x
))
2650 if (TARGET_ICT_MODEL_LARGE
&& nds32_indirect_call_referenced_p (x
))
2653 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
2654 during or after LRA/reload phase. */
2655 if (TARGET_CMODEL_LARGE
2656 && (reload_completed
2657 || reload_in_progress
2658 || lra_in_progress
))
2660 /* If -mcmodel=medium and the symbol references to rodata section,
2661 the 'symbol_ref' is not a valid address during or after
2662 LRA/reload phase. */
2663 if (TARGET_CMODEL_MEDIUM
2664 && (NDS32_SYMBOL_REF_RODATA_P (x
)
2665 || CONSTANT_POOL_ADDRESS_P (x
))
2666 && (reload_completed
2667 || reload_in_progress
2668 || lra_in_progress
))
2674 /* (mem (const (...)))
2675 => [ + const_addr ], where const_addr = symbol_ref + const_int */
2676 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
2678 rtx plus_op
= XEXP (x
, 0);
2680 rtx op0
= XEXP (plus_op
, 0);
2681 rtx op1
= XEXP (plus_op
, 1);
2683 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2685 /* Now we see the [ + const_addr ] pattern, but we need
2686 some further checking. */
2691 /* If -mcmodel=large, the 'const_addr' is not a valid address
2692 during or after LRA/reload phase. */
2693 if (TARGET_CMODEL_LARGE
2694 && (reload_completed
2695 || reload_in_progress
2696 || lra_in_progress
))
2698 /* If -mcmodel=medium and the symbol references to rodata section,
2699 the 'const_addr' is not a valid address during or after
2700 LRA/reload phase. */
2701 if (TARGET_CMODEL_MEDIUM
2702 && NDS32_SYMBOL_REF_RODATA_P (op0
)
2703 && (reload_completed
2704 || reload_in_progress
2705 || lra_in_progress
))
2708 /* At this point we can make sure 'const_addr' is a
2717 /* (mem (post_modify (reg) (plus (reg) (reg))))
2719 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2720 => [Ra], const_int */
2721 if (GET_CODE (XEXP (x
, 0)) == REG
2722 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2724 rtx plus_op
= XEXP (x
, 1);
2726 rtx op0
= XEXP (plus_op
, 0);
2727 rtx op1
= XEXP (plus_op
, 1);
2729 if (nds32_address_register_rtx_p (op0
, strict
)
2730 && nds32_legitimate_index_p (mode
, op1
, strict
))
2740 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2741 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2742 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2743 We only need to deal with register Ra. */
2744 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2750 /* (mem (plus reg const_int))
2752 /* (mem (plus reg reg))
2754 /* (mem (plus (mult reg const_int) reg))
2755 => [Ra + Rb << sv] */
2756 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2757 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
))
2759 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2760 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
))
2766 /* (mem (lo_sum (reg) (symbol_ref))) */
2767 /* (mem (lo_sum (reg) (const (plus (symbol_ref) (reg)))) */
2768 /* TLS case: (mem (lo_sum (reg) (const (unspec symbol_ref X)))) */
2769 /* The LO_SUM is a valid address if and only if we would like to
2770 generate 32-bit full address memory access with any of following
2773 2. -mcmodel=medium and the symbol_ref references to rodata. */
2780 if (!REG_P (XEXP (x
, 0)))
2783 if (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
2785 else if (GET_CODE (XEXP (x
, 1)) == CONST
)
2787 rtx plus
= XEXP(XEXP (x
, 1), 0);
2788 if (GET_CODE (plus
) == PLUS
)
2789 sym
= XEXP (plus
, 0);
2790 else if (GET_CODE (plus
) == UNSPEC
)
2791 sym
= XVECEXP (plus
, 0, 0);
2796 gcc_assert (GET_CODE (sym
) == SYMBOL_REF
);
2798 if (TARGET_ICT_MODEL_LARGE
2799 && nds32_indirect_call_referenced_p (sym
))
2802 if (TARGET_CMODEL_LARGE
)
2804 else if (TARGET_CMODEL_MEDIUM
2805 && NDS32_SYMBOL_REF_RODATA_P (sym
))
2817 nds32_legitimize_address (rtx x
,
2818 rtx oldx ATTRIBUTE_UNUSED
,
2819 machine_mode mode ATTRIBUTE_UNUSED
)
2821 if (nds32_tls_referenced_p (x
))
2822 x
= nds32_legitimize_tls_address (x
);
2823 else if (flag_pic
&& SYMBOLIC_CONST_P (x
))
2824 x
= nds32_legitimize_pic_address (x
);
2825 else if (TARGET_ICT_MODEL_LARGE
&& nds32_indirect_call_referenced_p (x
))
2826 x
= nds32_legitimize_ict_address (x
);
2832 nds32_legitimate_constant_p (machine_mode mode
, rtx x
)
2834 switch (GET_CODE (x
))
2837 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
2838 && (mode
== DFmode
|| mode
== SFmode
))
2844 if (GET_CODE (x
) == PLUS
)
2846 if (!CONST_INT_P (XEXP (x
, 1)))
2851 if (GET_CODE (x
) == UNSPEC
)
2853 switch (XINT (x
, 1))
2870 /* TLS symbols need a call to resolve in
2871 precompute_register_parameters. */
2872 if (SYMBOL_REF_TLS_MODEL (x
))
2882 /* Reorgnize the UNSPEC CONST and return its direct symbol. */
2884 nds32_delegitimize_address (rtx x
)
2886 x
= delegitimize_mem_from_attrs (x
);
2888 if (GET_CODE(x
) == CONST
)
2890 rtx inner
= XEXP (x
, 0);
2892 /* Handle for GOTOFF. */
2893 if (GET_CODE (inner
) == PLUS
)
2894 inner
= XEXP (inner
, 0);
2896 if (GET_CODE (inner
) == UNSPEC
)
2898 switch (XINT (inner
, 1))
2900 case UNSPEC_GOTINIT
:
2909 x
= XVECEXP (inner
, 0, 0);
2920 nds32_vectorize_preferred_simd_mode (scalar_mode mode
)
2922 if (!NDS32_EXT_DSP_P ())
2937 nds32_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2939 switch (GET_CODE (x
))
2942 return !nds32_legitimate_constant_p (mode
, x
);
2944 /* All symbols have to be accessed through gp-relative in PIC mode. */
2945 /* We don't want to force symbol as constant pool in .text section,
2946 because we use the gp-relatived instruction to load in small
2949 || SYMBOL_REF_TLS_MODEL (x
)
2950 || TARGET_CMODEL_SMALL
2951 || TARGET_CMODEL_MEDIUM
)
2956 if (flag_pic
&& (lra_in_progress
|| reload_completed
))
2966 /* Condition Code Status. */
2968 /* -- Representation of condition codes using registers. */
2971 nds32_canonicalize_comparison (int *code
,
2972 rtx
*op0 ATTRIBUTE_UNUSED
,
2974 bool op0_preserve_value ATTRIBUTE_UNUSED
)
2976 /* When the instruction combination pass tries to combine a comparison insn
2977 with its previous insns, it also transforms the operator in order to
2978 minimize its constant field. For example, it tries to transform a
2979 comparison insn from
2982 (const_int 10 [0xa])))
2986 (const_int 9 [0x9])))
2988 However, the nds32 target only provides instructions supporting the LTU
2989 operation directly, and the implementation of the pattern "cbranchsi4"
2990 only expands the LTU form. In order to handle the non-LTU operations
2991 generated from passes other than the RTL expansion pass, we have to
2992 implement this hook to revert those changes. Since we only expand the LTU
2993 operator in the RTL expansion pass, we might only need to handle the LEU
2994 case, unless we find other optimization passes perform more aggressive
2997 if (*code
== LEU
&& CONST_INT_P (*op1
))
2999 *op1
= gen_int_mode (INTVAL (*op1
) + 1, SImode
);
3005 /* Describing Relative Costs of Operations. */
3008 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3012 if ((from
== FP_REGS
&& to
!= FP_REGS
)
3013 || (from
!= FP_REGS
&& to
== FP_REGS
))
3015 else if (from
== HIGH_REGS
|| to
== HIGH_REGS
)
3016 return optimize_size
? 6 : 2;
3022 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3023 reg_class_t rclass ATTRIBUTE_UNUSED
,
3024 bool in ATTRIBUTE_UNUSED
)
3029 /* This target hook describes the relative costs of RTL expressions.
3030 Return 'true' when all subexpressions of x have been processed.
3031 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
3032 Refer to gcc/rtlanal.c for more information. */
3034 nds32_rtx_costs (rtx x
,
3041 return nds32_rtx_costs_impl (x
, mode
, outer_code
, opno
, total
, speed
);
3045 nds32_address_cost (rtx address
,
3050 return nds32_address_cost_impl (address
, mode
, as
, speed
);
3054 /* Dividing the Output into Sections (Texts, Data, . . . ). */
3056 /* If references to a symbol or a constant must be treated differently
3057 depending on something about the variable or function named by the symbol
3058 (such as what section it is in), we use this hook to store flags
3059 in symbol_ref rtx. */
3061 nds32_encode_section_info (tree decl
, rtx rtl
, int new_decl_p
)
3063 default_encode_section_info (decl
, rtl
, new_decl_p
);
3065 /* For the memory rtx, if it references to rodata section, we can store
3066 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
3067 nds32_legitimate_address_p() can determine how to treat such symbol_ref
3068 based on -mcmodel=X and this information. */
3069 if (MEM_P (rtl
) && MEM_READONLY_P (rtl
))
3071 rtx addr
= XEXP (rtl
, 0);
3073 if (GET_CODE (addr
) == SYMBOL_REF
)
3075 /* For (mem (symbol_ref X)) case. */
3076 SYMBOL_REF_FLAGS (addr
) |= NDS32_SYMBOL_FLAG_RODATA
;
3078 else if (GET_CODE (addr
) == CONST
3079 && GET_CODE (XEXP (addr
, 0)) == PLUS
)
3081 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
3082 rtx plus_op
= XEXP (addr
, 0);
3083 rtx op0
= XEXP (plus_op
, 0);
3084 rtx op1
= XEXP (plus_op
, 1);
3086 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
3087 SYMBOL_REF_FLAGS (op0
) |= NDS32_SYMBOL_FLAG_RODATA
;
3093 /* Defining the Output Assembler Language. */
3095 /* -- The Overall Framework of an Assembler File. */
3098 nds32_asm_file_start (void)
3100 default_file_start ();
3103 fprintf (asm_out_file
, "\t.pic\n");
3105 /* Tell assembler which ABI we are using. */
3106 fprintf (asm_out_file
, "\t! ABI version\n");
3107 if (TARGET_HARD_FLOAT
)
3108 fprintf (asm_out_file
, "\t.abi_2fp_plus\n");
3110 fprintf (asm_out_file
, "\t.abi_2\n");
3112 /* Tell assembler that this asm code is generated by compiler. */
3113 fprintf (asm_out_file
, "\t! This asm file is generated by compiler\n");
3114 fprintf (asm_out_file
, "\t.flag\tverbatim\n");
3116 if (TARGET_ICT_MODEL_LARGE
)
3117 fprintf (asm_out_file
, "\t.ict_model\tlarge\n");
3119 fprintf (asm_out_file
, "\t.ict_model\tsmall\n");
3120 /* Give assembler the size of each vector for interrupt handler. */
3121 fprintf (asm_out_file
, "\t! This vector size directive is required "
3122 "for checking inconsistency on interrupt handler\n");
3123 fprintf (asm_out_file
, "\t.vec_size\t%d\n", nds32_isr_vector_size
);
3125 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3128 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V2");
3130 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3");
3132 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3M");
3134 if (TARGET_CMODEL_SMALL
)
3135 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "SMALL");
3136 if (TARGET_CMODEL_MEDIUM
)
3137 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "MEDIUM");
3138 if (TARGET_CMODEL_LARGE
)
3139 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "LARGE");
3141 fprintf (asm_out_file
, "\t! Endian setting\t: %s\n",
3142 ((TARGET_BIG_ENDIAN
) ? "big-endian"
3143 : "little-endian"));
3144 fprintf (asm_out_file
, "\t! Use SP floating-point instruction\t: %s\n",
3145 ((TARGET_FPU_SINGLE
) ? "Yes"
3147 fprintf (asm_out_file
, "\t! Use DP floating-point instruction\t: %s\n",
3148 ((TARGET_FPU_DOUBLE
) ? "Yes"
3150 fprintf (asm_out_file
, "\t! ABI version\t\t: %s\n",
3151 ((TARGET_HARD_FLOAT
) ? "ABI2FP+"
3154 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3156 fprintf (asm_out_file
, "\t! Use conditional move\t\t: %s\n",
3157 ((TARGET_CMOV
) ? "Yes"
3159 fprintf (asm_out_file
, "\t! Use performance extension\t: %s\n",
3160 ((TARGET_EXT_PERF
) ? "Yes"
3162 fprintf (asm_out_file
, "\t! Use performance extension 2\t: %s\n",
3163 ((TARGET_EXT_PERF2
) ? "Yes"
3165 fprintf (asm_out_file
, "\t! Use string extension\t\t: %s\n",
3166 ((TARGET_EXT_STRING
) ? "Yes"
3169 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3171 fprintf (asm_out_file
, "\t! V3PUSH instructions\t: %s\n",
3172 ((TARGET_V3PUSH
) ? "Yes"
3174 fprintf (asm_out_file
, "\t! 16-bit instructions\t: %s\n",
3175 ((TARGET_16_BIT
) ? "Yes"
3177 fprintf (asm_out_file
, "\t! Reduced registers set\t: %s\n",
3178 ((TARGET_REDUCED_REGS
) ? "Yes"
3181 fprintf (asm_out_file
, "\t! Support unaligned access\t\t: %s\n",
3182 (flag_unaligned_access
? "Yes"
3185 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3188 fprintf (asm_out_file
, "\t! Optimization level\t: -Os\n");
3189 else if (optimize_fast
)
3190 fprintf (asm_out_file
, "\t! Optimization level\t: -Ofast\n");
3191 else if (optimize_debug
)
3192 fprintf (asm_out_file
, "\t! Optimization level\t: -Og\n");
3194 fprintf (asm_out_file
, "\t! Optimization level\t: -O%d\n", optimize
);
3196 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3198 fprintf (asm_out_file
, "\t! Cache block size\t: %d\n",
3199 nds32_cache_block_size
);
3201 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3203 nds32_asm_file_start_for_isr ();
3207 nds32_asm_file_end (void)
3209 nds32_asm_file_end_for_isr ();
3211 fprintf (asm_out_file
, "\t! ------------------------------------\n");
3215 nds32_asm_output_addr_const_extra (FILE *file
, rtx x
)
3217 if (GET_CODE (x
) == UNSPEC
)
3219 switch (XINT (x
, 1))
3221 case UNSPEC_GOTINIT
:
3222 output_addr_const (file
, XVECEXP (x
, 0, 0));
3225 output_addr_const (file
, XVECEXP (x
, 0, 0));
3226 fputs ("@GOTOFF", file
);
3229 output_addr_const (file
, XVECEXP (x
, 0, 0));
3230 fputs ("@GOT", file
);
3233 output_addr_const (file
, XVECEXP (x
, 0, 0));
3234 fputs ("@PLT", file
);
3237 output_addr_const (file
, XVECEXP (x
, 0, 0));
3238 fputs ("@TLSDESC", file
);
3241 output_addr_const (file
, XVECEXP (x
, 0, 0));
3242 fputs ("@TLSDESC", file
);
3245 output_addr_const (file
, XVECEXP (x
, 0, 0));
3246 fputs ("@GOTTPOFF", file
);
3249 output_addr_const (file
, XVECEXP (x
, 0, 0));
3250 fputs ("@TPOFF", file
);
3253 output_addr_const (file
, XVECEXP (x
, 0, 0));
3254 fputs ("@ICT", file
);
3265 /* -- Output and Generation of Labels. */
3268 nds32_asm_globalize_label (FILE *stream
, const char *name
)
3270 fputs ("\t.global\t", stream
);
3271 assemble_name (stream
, name
);
3272 fputs ("\n", stream
);
3275 /* -- Output of Assembler Instructions. */
3278 nds32_print_operand (FILE *stream
, rtx x
, int code
)
3280 HOST_WIDE_INT op_value
= 0;
3281 HOST_WIDE_INT one_position
;
3282 HOST_WIDE_INT zero_position
;
3283 bool pick_lsb_p
= false;
3284 bool pick_msb_p
= false;
3287 if (CONST_INT_P (x
))
3288 op_value
= INTVAL (x
);
3293 /* Do nothing special. */
3297 /* Use exact_log2() to search the 0-bit position. */
3298 gcc_assert (CONST_INT_P (x
));
3299 zero_position
= exact_log2 (~UINTVAL (x
) & GET_MODE_MASK (SImode
));
3300 gcc_assert (zero_position
!= -1);
3301 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, zero_position
);
3303 /* No need to handle following process, so return immediately. */
3307 gcc_assert (MEM_P (x
)
3308 && GET_CODE (XEXP (x
, 0)) == PLUS
3309 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
3310 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (XEXP (XEXP (x
, 0), 1)));
3312 /* No need to handle following process, so return immediately. */
3316 gcc_assert (CONST_INT_P (x
)
3320 || INTVAL (x
) == 24));
3321 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) / 8);
3323 /* No need to handle following process, so return immediately. */
3327 /* Use exact_log2() to search the 1-bit position. */
3328 gcc_assert (CONST_INT_P (x
));
3329 one_position
= exact_log2 (UINTVAL (x
) & GET_MODE_MASK (SImode
));
3330 gcc_assert (one_position
!= -1);
3331 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, one_position
);
3333 /* No need to handle following process, so return immediately. */
3337 /* X is supposed to be REG rtx. */
3338 gcc_assert (REG_P (x
));
3339 /* Claim that we are going to pick LSB part of X. */
3344 /* X is supposed to be REG rtx. */
3345 gcc_assert (REG_P (x
));
3346 /* Claim that we are going to pick MSB part of X. */
3351 /* 'x' is supposed to be CONST_INT, get the value. */
3352 gcc_assert (CONST_INT_P (x
));
3354 /* According to the Andes architecture,
3355 the system/user register index range is 0 ~ 1023.
3356 In order to avoid conflict between user-specified-integer value
3357 and enum-specified-register value,
3358 the 'enum nds32_intrinsic_registers' value
3359 in nds32_intrinsic.h starts from 1024. */
3360 if (op_value
< 1024 && op_value
>= 0)
3362 /* If user gives integer value directly (0~1023),
3363 we just print out the value. */
3364 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, op_value
);
3366 else if (op_value
< 0
3367 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
3370 /* The enum index value for array size is out of range. */
3371 error ("intrinsic register index is out of range");
3375 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3376 we can print out register name. Remember to substract 1024. */
3377 fprintf (stream
, "%s",
3378 nds32_intrinsic_register_names
[op_value
- 1024]);
3381 /* No need to handle following process, so return immediately. */
3384 case 'R': /* cctl valck */
3385 /* Note the cctl divide to 5 group and share the same name table. */
3386 if (op_value
< 0 || op_value
> 4)
3387 error ("CCTL intrinsic function subtype out of range!");
3388 fprintf (stream
, "%s", nds32_cctl_names
[op_value
]);
3391 case 'T': /* cctl idxwbinv */
3392 /* Note the cctl divide to 5 group and share the same name table. */
3393 if (op_value
< 0 || op_value
> 4)
3394 error ("CCTL intrinsic function subtype out of range!");
3395 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 4]);
3398 case 'U': /* cctl vawbinv */
3399 /* Note the cctl divide to 5 group and share the same name table. */
3400 if (op_value
< 0 || op_value
> 4)
3401 error ("CCTL intrinsic function subtype out of range!");
3402 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 8]);
3405 case 'X': /* cctl idxread */
3406 /* Note the cctl divide to 5 group and share the same name table. */
3407 if (op_value
< 0 || op_value
> 4)
3408 error ("CCTL intrinsic function subtype out of range!");
3409 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 12]);
3412 case 'W': /* cctl idxwitre */
3413 /* Note the cctl divide to 5 group and share the same name table. */
3414 if (op_value
< 0 || op_value
> 4)
3415 error ("CCTL intrinsic function subtype out of range!");
3416 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 16]);
3419 case 'Z': /* dpref */
3420 fprintf (stream
, "%s", nds32_dpref_names
[op_value
]);
3425 output_operand_lossage ("invalid operand output code");
3429 switch (GET_CODE (x
))
3432 output_addr_const (stream
, x
);
3436 output_addr_const (stream
, x
);
3438 if (nds32_indirect_call_referenced_p (x
))
3439 fprintf (stream
, "@ICT");
3444 /* Print a Double-precision register name. */
3445 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3446 && NDS32_IS_FPR_REGNUM (REGNO (x
)))
3449 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
))
3451 output_operand_lossage ("invalid operand for code '%c'", code
);
3454 fprintf (stream
, "$fd%d", (regno
- NDS32_FIRST_FPR_REGNUM
) >> 1);
3458 /* Print LSB or MSB part of register pair if the
3459 constraint modifier 'L' or 'H' is specified. */
3460 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3461 && NDS32_IS_GPR_REGNUM (REGNO (x
)))
3463 if ((pick_lsb_p
&& WORDS_BIG_ENDIAN
)
3464 || (pick_msb_p
&& !WORDS_BIG_ENDIAN
))
3466 /* If we would like to print out LSB register under big-endian,
3467 or print out MSB register under little-endian, we need to
3468 increase register number. */
3471 fputs (reg_names
[regno
], stream
);
3476 /* Forbid using static chain register ($r16)
3477 on reduced-set registers configuration. */
3478 if (TARGET_REDUCED_REGS
3479 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3480 sorry ("a nested function is not supported for reduced registers");
3482 /* Normal cases, print out register name. */
3483 fputs (reg_names
[REGNO (x
)], stream
);
3487 output_address (GET_MODE (x
), XEXP (x
, 0));
3491 if (GET_CODE (XEXP (x
, 0)) == CONST_DOUBLE
)
3493 const REAL_VALUE_TYPE
*rv
;
3495 gcc_assert (GET_MODE (x
) == SFmode
);
3497 rv
= CONST_DOUBLE_REAL_VALUE (XEXP (x
, 0));
3498 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3500 fprintf (stream
, "hi20(0x%lx)", val
);
3507 const REAL_VALUE_TYPE
*rv
;
3509 gcc_assert (GET_MODE (x
) == SFmode
);
3511 rv
= CONST_DOUBLE_REAL_VALUE (x
);
3512 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3514 fprintf (stream
, "0x%lx", val
);
3520 output_addr_const (stream
, x
);
3524 fprintf (stream
, HOST_WIDE_INT_PRINT_HEX
, const_vector_to_hwint (x
));
3528 /* This is a special case for inline assembly using memory address 'p'.
3529 The inline assembly code is expected to use pesudo instruction
3530 for the operand. EX: la */
3531 output_addr_const (stream
, XEXP(x
, 1));
3535 /* Generally, output_addr_const () is able to handle most cases.
3536 We want to see what CODE could appear,
3537 so we use gcc_unreachable() to stop it. */
3545 nds32_print_operand_address (FILE *stream
,
3546 machine_mode mode ATTRIBUTE_UNUSED
,
3551 switch (GET_CODE (x
))
3555 /* [ + symbol_ref] */
3556 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3557 fputs ("[ + ", stream
);
3558 output_addr_const (stream
, x
);
3559 fputs ("]", stream
);
3563 /* This is a special case for inline assembly using memory operand 'm'.
3564 The inline assembly code is expected to use pesudo instruction
3565 for the operand. EX: [ls].[bhw] */
3566 fputs ("[ + ", stream
);
3568 output_addr_const (stream
, op1
);
3569 fputs ("]", stream
);
3573 /* Forbid using static chain register ($r16)
3574 on reduced-set registers configuration. */
3575 if (TARGET_REDUCED_REGS
3576 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3577 sorry ("a nested function is not supported for reduced registers");
3580 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
3587 /* Checking op0, forbid using static chain register ($r16)
3588 on reduced-set registers configuration. */
3589 if (TARGET_REDUCED_REGS
3591 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3592 sorry ("a nested function is not supported for reduced registers");
3593 /* Checking op1, forbid using static chain register ($r16)
3594 on reduced-set registers configuration. */
3595 if (TARGET_REDUCED_REGS
3597 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3598 sorry ("a nested function is not supported for reduced registers");
3600 if (REG_P (op0
) && CONST_INT_P (op1
))
3603 fprintf (stream
, "[%s + (" HOST_WIDE_INT_PRINT_DEC
")]",
3604 reg_names
[REGNO (op0
)], INTVAL (op1
));
3606 else if (REG_P (op0
) && REG_P (op1
))
3609 fprintf (stream
, "[%s + %s]",
3610 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3612 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
3615 From observation, the pattern looks like:
3616 (plus:SI (mult:SI (reg:SI 58)
3617 (const_int 4 [0x4]))
3621 /* We need to set sv to output shift value. */
3622 if (INTVAL (XEXP (op0
, 1)) == 1)
3624 else if (INTVAL (XEXP (op0
, 1)) == 2)
3626 else if (INTVAL (XEXP (op0
, 1)) == 4)
3628 else if (INTVAL (XEXP (op0
, 1)) == 8)
3633 fprintf (stream
, "[%s + %s << %d]",
3634 reg_names
[REGNO (op1
)],
3635 reg_names
[REGNO (XEXP (op0
, 0))],
3638 else if (GET_CODE (op0
) == ASHIFT
&& REG_P (op1
))
3641 In normal, ASHIFT can be converted to MULT like above case.
3642 But when the address rtx does not go through canonicalize_address
3643 defined in fwprop, we'll need this case. */
3644 int sv
= INTVAL (XEXP (op0
, 1));
3645 gcc_assert (sv
<= 3 && sv
>=0);
3647 fprintf (stream
, "[%s + %s << %d]",
3648 reg_names
[REGNO (op1
)],
3649 reg_names
[REGNO (XEXP (op0
, 0))],
3654 /* The control flow is not supposed to be here. */
3662 /* (post_modify (regA) (plus (regA) (regB)))
3663 (post_modify (regA) (plus (regA) (const_int)))
3664 We would like to extract
3665 regA and regB (or const_int) from plus rtx. */
3666 op0
= XEXP (XEXP (x
, 1), 0);
3667 op1
= XEXP (XEXP (x
, 1), 1);
3669 /* Checking op0, forbid using static chain register ($r16)
3670 on reduced-set registers configuration. */
3671 if (TARGET_REDUCED_REGS
3673 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3674 sorry ("a nested function is not supported for reduced registers");
3675 /* Checking op1, forbid using static chain register ($r16)
3676 on reduced-set registers configuration. */
3677 if (TARGET_REDUCED_REGS
3679 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3680 sorry ("a nested function is not supported for reduced registers");
3682 if (REG_P (op0
) && REG_P (op1
))
3685 fprintf (stream
, "[%s], %s",
3686 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3688 else if (REG_P (op0
) && CONST_INT_P (op1
))
3691 fprintf (stream
, "[%s], " HOST_WIDE_INT_PRINT_DEC
,
3692 reg_names
[REGNO (op0
)], INTVAL (op1
));
3696 /* The control flow is not supposed to be here. */
3707 /* Checking op0, forbid using static chain register ($r16)
3708 on reduced-set registers configuration. */
3709 if (TARGET_REDUCED_REGS
3711 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3712 sorry ("a nested function is not supported for reduced registers");
3716 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3717 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3718 We only need to deal with register Ra. */
3719 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
3723 /* The control flow is not supposed to be here. */
3731 /* Generally, output_addr_const () is able to handle most cases.
3732 We want to see what CODE could appear,
3733 so we use gcc_unreachable() to stop it. */
3740 /* -- Assembler Commands for Exception Regions. */
3743 nds32_dwarf_register_span (rtx reg
)
3745 rtx dwarf_high
, dwarf_low
;
3750 mode
= GET_MODE (reg
);
3751 regno
= REGNO (reg
);
3753 /* We need to adjust dwarf register information for floating-point registers
3754 rather than using default register number mapping. */
3755 if (regno
>= NDS32_FIRST_FPR_REGNUM
3756 && regno
<= NDS32_LAST_FPR_REGNUM
)
3758 if (mode
== DFmode
|| mode
== SCmode
)
3760 /* By default, GCC maps increasing register numbers to increasing
3761 memory locations, but paired FPRs in NDS32 target are always
3767 We must return parallel rtx to represent such layout. */
3768 dwarf_high
= gen_rtx_REG (word_mode
, regno
);
3769 dwarf_low
= gen_rtx_REG (word_mode
, regno
+ 1);
3770 return gen_rtx_PARALLEL (VOIDmode
,
3771 gen_rtvec (2, dwarf_low
, dwarf_high
));
3773 else if (mode
== DCmode
)
3775 rtx dwarf_high_re
= gen_rtx_REG (word_mode
, regno
);
3776 rtx dwarf_low_re
= gen_rtx_REG (word_mode
, regno
+ 1);
3777 rtx dwarf_high_im
= gen_rtx_REG (word_mode
, regno
);
3778 rtx dwarf_low_im
= gen_rtx_REG (word_mode
, regno
+ 1);
3779 return gen_rtx_PARALLEL (VOIDmode
,
3780 gen_rtvec (4, dwarf_low_re
, dwarf_high_re
,
3781 dwarf_high_im
, dwarf_low_im
));
3783 else if (mode
== SFmode
|| mode
== SImode
)
3785 /* Create new dwarf information with adjusted register number. */
3786 dwarf_single
= gen_rtx_REG (word_mode
, regno
);
3787 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, dwarf_single
));
3791 /* We should not be here. */
3799 /* Map internal gcc register numbers to DWARF2 register numbers. */
3802 nds32_dbx_register_number (unsigned int regno
)
3804 /* The nds32 port in GDB maintains a mapping between dwarf register
3805 number and displayed register name. For backward compatibility to
3806 previous toolchain, currently our gdb still has four registers
3807 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3808 does not count those four registers in its register number table.
3809 So we have to add 4 on its register number and then create new
3810 dwarf information. Hopefully we can discard such workaround
3812 if (NDS32_IS_FPR_REGNUM (regno
))
3819 /* Defining target-specific uses of __attribute__. */
3821 /* Add some checking after merging attributes. */
3823 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
3825 tree combined_attrs
;
3827 /* Create combined attributes. */
3828 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
3829 DECL_ATTRIBUTES (newdecl
));
3831 /* Since newdecl is acutally a duplicate of olddecl,
3832 we can take olddecl for some operations. */
3833 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
3835 /* Check isr-specific attributes conflict. */
3836 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
3839 return combined_attrs
;
3842 /* Add some checking when inserting attributes. */
3844 nds32_insert_attributes (tree decl
, tree
*attributes
)
3846 /* A "indirect_call" function attribute implies "noinline" and "noclone"
3847 for elf toolchain to support ROM patch mechanism. */
3848 if (TREE_CODE (decl
) == FUNCTION_DECL
3849 && lookup_attribute ("indirect_call", *attributes
) != NULL
)
3851 tree new_attrs
= *attributes
;
3853 if (lookup_attribute ("noinline", new_attrs
) == NULL
)
3854 new_attrs
= tree_cons (get_identifier ("noinline"), NULL
, new_attrs
);
3855 if (lookup_attribute ("noclone", new_attrs
) == NULL
)
3856 new_attrs
= tree_cons (get_identifier ("noclone"), NULL
, new_attrs
);
3858 if (!TREE_PUBLIC (decl
))
3859 error("indirect_call attribute can't apply for static function");
3861 *attributes
= new_attrs
;
3864 /* For function declaration, we need to check isr-specific attributes:
3865 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3866 2. Check valid integer value for interrupt/exception.
3867 3. Check valid integer value for reset.
3868 4. Check valid function for nmi/warm. */
3869 if (TREE_CODE (decl
) == FUNCTION_DECL
)
3872 tree intr
, excp
, reset
;
3874 /* Pick up function attributes. */
3875 func_attrs
= *attributes
;
3877 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3878 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
3880 /* Now we are starting to check valid id value
3881 for interrupt/exception/reset.
3882 Note that we ONLY check its validity here.
3883 To construct isr vector information, it is still performed
3884 by nds32_construct_isr_vectors_information(). */
3885 intr
= lookup_attribute ("interrupt", func_attrs
);
3886 excp
= lookup_attribute ("exception", func_attrs
);
3887 reset
= lookup_attribute ("reset", func_attrs
);
3891 /* Deal with interrupt/exception. */
3893 unsigned int lower_bound
, upper_bound
;
3895 /* The way to handle interrupt or exception is the same,
3896 we just need to take care of actual vector number.
3897 For interrupt(0..63), the actual vector number is (9..72).
3898 For exception(1..8), the actual vector number is (1..8). */
3899 lower_bound
= (intr
) ? (0) : (1);
3900 upper_bound
= (intr
) ? (63) : (8);
3902 /* Prepare id list so that we can traverse id value. */
3903 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
3905 /* 2. Check valid integer value for interrupt/exception. */
3910 /* Pick up each vector id value. */
3911 id
= TREE_VALUE (id_list
);
3912 /* Issue error if it is not a valid integer value. */
3913 if (TREE_CODE (id
) != INTEGER_CST
3914 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3915 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3916 error ("invalid id value for interrupt/exception attribute");
3918 /* Advance to next id. */
3919 id_list
= TREE_CHAIN (id_list
);
3924 /* Deal with reset. */
3928 unsigned int lower_bound
;
3929 unsigned int upper_bound
;
3931 /* Prepare id_list and identify id value so that
3932 we can check if total number of vectors is valid. */
3933 id_list
= TREE_VALUE (reset
);
3934 id
= TREE_VALUE (id_list
);
3936 /* The maximum numbers for user's interrupt is 64. */
3940 /* 3. Check valid integer value for reset. */
3941 if (TREE_CODE (id
) != INTEGER_CST
3942 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3943 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3944 error ("invalid id value for reset attribute");
3946 /* 4. Check valid function for nmi/warm. */
3947 nmi
= lookup_attribute ("nmi", func_attrs
);
3948 warm
= lookup_attribute ("warm", func_attrs
);
3950 if (nmi
!= NULL_TREE
)
3955 nmi_func_list
= TREE_VALUE (nmi
);
3956 nmi_func
= TREE_VALUE (nmi_func_list
);
3958 /* Issue error if it is not a valid nmi function. */
3959 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
3960 error ("invalid nmi function for reset attribute");
3963 if (warm
!= NULL_TREE
)
3965 tree warm_func_list
;
3968 warm_func_list
= TREE_VALUE (warm
);
3969 warm_func
= TREE_VALUE (warm_func_list
);
3971 /* Issue error if it is not a valid warm function. */
3972 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
3973 error ("invalid warm function for reset attribute");
3978 /* No interrupt, exception, or reset attribute is set. */
3985 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
3986 tree pop_target ATTRIBUTE_UNUSED
)
3988 /* Currently, we do not parse any pragma target by ourself,
3989 so just simply return false. */
3994 nds32_option_override (void)
3996 /* After all the command options have been parsed,
3997 we shall deal with some flags for changing compiler settings. */
3999 /* At first, we check if we have to strictly
4000 set some flags based on ISA family. */
4003 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
4004 target_flags
&= ~MASK_V3PUSH
;
4008 /* Under V3 ISA, currently nothing should be strictly set. */
4012 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
4013 target_flags
|= MASK_REDUCED_REGS
;
4014 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
4015 target_flags
&= ~MASK_EXT_PERF
;
4016 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
4017 target_flags
&= ~MASK_EXT_PERF2
;
4018 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
4019 target_flags
&= ~MASK_EXT_STRING
;
4022 error ("not support -fpic option for v3m toolchain");
4025 /* See if we are using reduced-set registers:
4026 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
4027 If so, we must forbid using $r11~$r14, $r16~$r27. */
4028 if (TARGET_REDUCED_REGS
)
4032 /* Prevent register allocator from
4033 choosing it as doing register allocation. */
4034 for (r
= 11; r
<= 14; r
++)
4035 fixed_regs
[r
] = call_used_regs
[r
] = 1;
4036 for (r
= 16; r
<= 27; r
++)
4037 fixed_regs
[r
] = call_used_regs
[r
] = 1;
4042 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
4043 target_flags
&= ~MASK_V3PUSH
;
4046 if (TARGET_HARD_FLOAT
&& !(TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
4048 if (nds32_arch_option
== ARCH_V3S
|| nds32_arch_option
== ARCH_V3F
)
4049 error ("Disable FPU ISA, "
4050 "the ABI option must be enable '-mfloat-abi=soft'");
4052 error ("'-mabi=2fp+' option only support when FPU available, "
4053 "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
4057 nds32_register_passes ();
4061 /* Miscellaneous Parameters. */
4064 nds32_md_asm_adjust (vec
<rtx
> &outputs ATTRIBUTE_UNUSED
,
4065 vec
<rtx
> &inputs ATTRIBUTE_UNUSED
,
4066 vec
<const char *> &constraints ATTRIBUTE_UNUSED
,
4067 vec
<rtx
> &clobbers
, HARD_REG_SET
&clobbered_regs
)
4069 clobbers
.safe_push (gen_rtx_REG (SImode
, TA_REGNUM
));
4070 SET_HARD_REG_BIT (clobbered_regs
, TA_REGNUM
);
4075 nds32_init_builtins (void)
4077 nds32_init_builtins_impl ();
4081 nds32_builtin_decl (unsigned code
, bool initialize_p
)
4083 /* Implement in nds32-intrinsic.c. */
4084 return nds32_builtin_decl_impl (code
, initialize_p
);
4088 nds32_expand_builtin (tree exp
,
4094 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
4098 /* ------------------------------------------------------------------------ */
4100 /* PART 4: Implemet extern function definitions,
4101 the prototype is in nds32-protos.h. */
4103 /* Run-time Target Specification. */
4106 nds32_cpu_cpp_builtins(struct cpp_reader
*pfile
)
4108 #define builtin_define(TXT) cpp_define (pfile, TXT)
4109 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
4110 builtin_define ("__nds32__");
4111 builtin_define ("__NDS32__");
4113 if (TARGET_HARD_FLOAT
)
4114 builtin_define ("__NDS32_ABI_2FP_PLUS__");
4116 builtin_define ("__NDS32_ABI_2__");
4119 builtin_define ("__NDS32_ISA_V2__");
4121 builtin_define ("__NDS32_ISA_V3__");
4123 builtin_define ("__NDS32_ISA_V3M__");
4125 if (TARGET_FPU_SINGLE
)
4126 builtin_define ("__NDS32_EXT_FPU_SP__");
4127 if (TARGET_FPU_DOUBLE
)
4128 builtin_define ("__NDS32_EXT_FPU_DP__");
4130 if (TARGET_EXT_FPU_FMA
)
4131 builtin_define ("__NDS32_EXT_FPU_FMA__");
4132 if (NDS32_EXT_FPU_DOT_E
)
4133 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
4134 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
4136 switch (nds32_fp_regnum
)
4140 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
4144 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
4148 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
4152 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
4159 if (TARGET_BIG_ENDIAN
)
4160 builtin_define ("__NDS32_EB__");
4162 builtin_define ("__NDS32_EL__");
4164 if (TARGET_REDUCED_REGS
)
4165 builtin_define ("__NDS32_REDUCED_REGS__");
4167 builtin_define ("__NDS32_CMOV__");
4168 if (TARGET_EXT_PERF
)
4169 builtin_define ("__NDS32_EXT_PERF__");
4170 if (TARGET_EXT_PERF2
)
4171 builtin_define ("__NDS32_EXT_PERF2__");
4172 if (TARGET_EXT_STRING
)
4173 builtin_define ("__NDS32_EXT_STRING__");
4175 builtin_define ("__NDS32_16_BIT__");
4176 if (TARGET_GP_DIRECT
)
4177 builtin_define ("__NDS32_GP_DIRECT__");
4179 builtin_define ("__NDS32_VH__");
4180 if (NDS32_EXT_DSP_P ())
4181 builtin_define ("__NDS32_EXT_DSP__");
4183 if (TARGET_BIG_ENDIAN
)
4184 builtin_define ("__big_endian__");
4186 builtin_assert ("cpu=nds32");
4187 builtin_assert ("machine=nds32");
4189 if (TARGET_HARD_FLOAT
)
4190 builtin_define ("__NDS32_ABI_2FP_PLUS");
4192 builtin_define ("__NDS32_ABI_2");
4194 #undef builtin_define
4195 #undef builtin_assert
4199 /* Defining Data Structures for Per-function Information. */
4202 nds32_init_expanders (void)
4204 /* Arrange to initialize and mark the machine per-function status. */
4205 init_machine_status
= nds32_init_machine_status
;
4209 /* Register Usage. */
4211 /* -- Order of Allocation of Registers. */
4214 nds32_adjust_reg_alloc_order (void)
4216 const int nds32_reg_alloc_order
[] = REG_ALLOC_ORDER
;
4218 /* Copy the default register allocation order, which is designed
4219 to optimize for code size. */
4220 memcpy(reg_alloc_order
, nds32_reg_alloc_order
, sizeof (reg_alloc_order
));
4222 /* Adjust few register allocation order when optimizing for speed. */
4225 memcpy (reg_alloc_order
, nds32_reg_alloc_order_for_speed
,
4226 sizeof (nds32_reg_alloc_order_for_speed
));
4230 /* -- How Values Fit in Registers. */
4233 nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED
,
4236 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
4239 /* Implement TARGET_HARD_REGNO_MODE_OK. */
4242 nds32_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
4244 if (regno
> FIRST_PSEUDO_REGISTER
)
4247 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
) && NDS32_IS_FPR_REGNUM (regno
))
4249 if (NDS32_IS_EXT_FPR_REGNUM(regno
))
4250 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno
) && (mode
== DFmode
));
4251 else if (mode
== SFmode
|| mode
== SImode
)
4252 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno
);
4253 else if (mode
== DFmode
)
4254 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
);
4259 /* Restrict double-word quantities to even register pairs. */
4260 if (regno
<= NDS32_LAST_GPR_REGNUM
)
4261 return (targetm
.hard_regno_nregs (regno
, mode
) == 1
4267 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
4268 tie QI/HI/SI modes together. */
4271 nds32_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
4273 if ((GET_MODE_CLASS (mode1
) == MODE_INT
4274 && GET_MODE_CLASS (mode2
) == MODE_INT
)
4275 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
4276 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
)
4279 if (GET_MODE_SIZE (mode1
) == GET_MODE_SIZE (mode2
))
4281 if ((TARGET_FPU_SINGLE
&& !TARGET_FPU_DOUBLE
)
4282 && (mode1
== DFmode
|| mode2
== DFmode
))
4291 /* Register Classes. */
4294 nds32_regno_reg_class (int regno
)
4296 /* Refer to nds32.h for more register class details. */
4298 if (regno
>= 0 && regno
<= 7)
4300 else if (regno
>= 8 && regno
<= 11)
4302 else if (regno
>= 12 && regno
<= 14)
4304 else if (regno
== 15)
4306 else if (regno
>= 16 && regno
<= 19)
4308 else if (regno
>= 20 && regno
<= 31)
4310 else if (regno
== 32 || regno
== 33)
4312 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
4313 know how to allocate register for $SFP and $AP, just tell IRA they
4314 are GENERAL_REGS, and ARM do this hack too. */
4315 return GENERAL_REGS
;
4317 else if (regno
>= 34 && regno
<= 97)
4324 /* Stack Layout and Calling Conventions. */
4326 /* -- Basic Stack Layout. */
4329 nds32_dynamic_chain_address (rtx frameaddr
)
4333 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
4334 We can access dynamic chain address from stack by [$fp - 12]. */
4335 return plus_constant (Pmode
, frameaddr
, -12);
4339 /* For general case we push $fp and $lp into stack at prologue.
4340 We can access dynamic chain address from stack by [$fp - 8]. */
4341 return plus_constant (Pmode
, frameaddr
, -8);
4346 nds32_return_addr_rtx (int count
,
4354 /* In nds32 ABI design, we can expect that $lp is always available
4355 from stack by [$fp - 4] location. */
4357 addr
= plus_constant (Pmode
, frameaddr
, offset
);
4358 addr
= memory_address (Pmode
, addr
);
4360 return gen_rtx_MEM (Pmode
, addr
);
4363 /* If count == 0, it means we are at current frame,
4364 the return address is $r30 ($lp). */
4365 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
4368 /* -- Eliminating Frame Pointer and Arg Pointer. */
4371 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
4373 HOST_WIDE_INT offset
;
4375 /* Compute and setup stack frame size.
4376 The result will be in cfun->machine. */
4377 nds32_compute_stack_frame ();
4379 /* Remember to consider
4380 cfun->machine->callee_saved_area_gpr_padding_bytes and
4381 cfun->machine->eh_return_data_regs_size
4382 when calculating offset. */
4383 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
4385 offset
= (cfun
->machine
->fp_size
4386 + cfun
->machine
->gp_size
4387 + cfun
->machine
->lp_size
4388 + cfun
->machine
->callee_saved_gpr_regs_size
4389 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4390 + cfun
->machine
->callee_saved_fpr_regs_size
4391 + cfun
->machine
->eh_return_data_regs_size
4392 + cfun
->machine
->local_size
4393 + cfun
->machine
->out_args_size
);
4395 else if (from_reg
== ARG_POINTER_REGNUM
4396 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
4400 else if (from_reg
== FRAME_POINTER_REGNUM
4401 && to_reg
== STACK_POINTER_REGNUM
)
4403 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
4405 else if (from_reg
== FRAME_POINTER_REGNUM
4406 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
4408 offset
= (-1) * (cfun
->machine
->fp_size
4409 + cfun
->machine
->gp_size
4410 + cfun
->machine
->lp_size
4411 + cfun
->machine
->callee_saved_gpr_regs_size
4412 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4413 + cfun
->machine
->callee_saved_fpr_regs_size
4414 + cfun
->machine
->eh_return_data_regs_size
);
4424 /* -- Passing Arguments in Registers. */
4427 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4428 tree fntype ATTRIBUTE_UNUSED
,
4429 rtx libname ATTRIBUTE_UNUSED
,
4430 tree fndecl ATTRIBUTE_UNUSED
,
4431 int n_named_args ATTRIBUTE_UNUSED
)
4433 /* Initial available registers. The values are offset against
4434 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
4435 for passing arguments. */
4436 cum
->gpr_offset
= 0;
4437 cum
->fpr_offset
= 0;
4440 /* -- Function Entry and Exit. */
4442 /* Function for normal multiple push prologue. */
4444 nds32_expand_prologue (void)
4450 /* Compute and setup stack frame size.
4451 The result will be in cfun->machine. */
4452 nds32_compute_stack_frame ();
4454 /* If this is a variadic function, first we need to push argument
4455 registers that hold the unnamed argument value. */
4456 if (cfun
->machine
->va_args_size
!= 0)
4458 Rb
= cfun
->machine
->va_args_first_regno
;
4459 Re
= cfun
->machine
->va_args_last_regno
;
4460 /* No need to push $fp, $gp, or $lp. */
4461 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, true);
4463 /* We may also need to adjust stack pointer for padding bytes
4464 because varargs may cause $sp not 8-byte aligned. */
4465 if (cfun
->machine
->va_args_area_padding_bytes
)
4467 /* Generate sp adjustment instruction. */
4468 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
4470 nds32_emit_adjust_frame (stack_pointer_rtx
,
4476 /* If the function is 'naked',
4477 we do not have to generate prologue code fragment. */
4478 if (cfun
->machine
->naked_p
&& !flag_pic
)
4481 /* Get callee_first_regno and callee_last_regno. */
4482 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4483 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4485 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4486 to be saved, we don't have to create multiple push instruction.
4487 Otherwise, a multiple push instruction is needed. */
4488 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4489 && cfun
->machine
->fp_size
== 0
4490 && cfun
->machine
->gp_size
== 0
4491 && cfun
->machine
->lp_size
== 0))
4493 /* Create multiple push instruction rtx. */
4494 nds32_emit_stack_push_multiple (
4496 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
,
4500 /* Save eh data registers. */
4501 if (cfun
->machine
->use_eh_return_p
)
4503 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4504 Re
= cfun
->machine
->eh_return_data_last_regno
;
4506 /* No need to push $fp, $gp, or $lp.
4507 Also, this is not variadic arguments push. */
4508 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, false);
4511 /* Check frame_pointer_needed to see
4512 if we shall emit fp adjustment instruction. */
4513 if (frame_pointer_needed
)
4515 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
4516 + (4 * callee-saved-registers)
4517 + (4 * exception-handling-data-registers)
4518 Note: No need to adjust
4519 cfun->machine->callee_saved_area_gpr_padding_bytes,
4520 because, at this point, stack pointer is just
4521 at the position after push instruction. */
4522 fp_adjust
= cfun
->machine
->fp_size
4523 + cfun
->machine
->gp_size
4524 + cfun
->machine
->lp_size
4525 + cfun
->machine
->callee_saved_gpr_regs_size
4526 + cfun
->machine
->eh_return_data_regs_size
;
4528 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4533 /* Save fpu registers. */
4534 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4536 /* When $sp moved to bottom of stack, we need to check whether
4537 the range of offset in the FPU instruction. */
4538 int fpr_offset
= cfun
->machine
->local_size
4539 + cfun
->machine
->out_args_size
4540 + cfun
->machine
->callee_saved_fpr_regs_size
;
4542 /* Check FPU instruction offset imm14s. */
4543 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset
)))
4545 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4546 + cfun
->machine
->callee_saved_fpr_regs_size
;
4548 /* Save fpu registers, need to allocate stack space
4549 for fpu callee registers. And now $sp position
4550 on callee saved fpr registers. */
4551 nds32_emit_adjust_frame (stack_pointer_rtx
,
4555 /* Emit fpu store instruction, using [$sp + offset] store
4557 nds32_emit_push_fpr_callee_saved (0);
4559 /* Adjust $sp = $sp - local_size - out_args_size. */
4560 sp_adjust
= cfun
->machine
->local_size
4561 + cfun
->machine
->out_args_size
;
4563 /* Allocate stack space for local size and out args size. */
4564 nds32_emit_adjust_frame (stack_pointer_rtx
,
4570 /* Offset range in Is14, so $sp moved to bottom of stack. */
4572 /* Adjust $sp = $sp - local_size - out_args_size
4573 - callee_saved_area_gpr_padding_bytes
4574 - callee_saved_fpr_regs_size. */
4575 sp_adjust
= cfun
->machine
->local_size
4576 + cfun
->machine
->out_args_size
4577 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4578 + cfun
->machine
->callee_saved_fpr_regs_size
;
4580 nds32_emit_adjust_frame (stack_pointer_rtx
,
4584 /* Emit fpu store instruction, using [$sp + offset] store
4586 int fpr_position
= cfun
->machine
->out_args_size
4587 + cfun
->machine
->local_size
;
4588 nds32_emit_push_fpr_callee_saved (fpr_position
);
4593 /* Adjust $sp = $sp - local_size - out_args_size
4594 - callee_saved_area_gpr_padding_bytes. */
4595 sp_adjust
= cfun
->machine
->local_size
4596 + cfun
->machine
->out_args_size
4597 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4599 /* sp_adjust value may be out of range of the addi instruction,
4600 create alternative add behavior with TA_REGNUM if necessary,
4601 using NEGATIVE value to tell that we are decreasing address. */
4602 nds32_emit_adjust_frame (stack_pointer_rtx
,
4607 /* Emit gp setup instructions for -fpic. */
4608 if (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
))
4609 nds32_emit_load_gp ();
4611 /* Prevent the instruction scheduler from
4612 moving instructions across the boundary. */
4613 emit_insn (gen_blockage ());
4616 /* Function for normal multiple pop epilogue. */
4618 nds32_expand_epilogue (bool sibcall_p
)
4623 /* Compute and setup stack frame size.
4624 The result will be in cfun->machine. */
4625 nds32_compute_stack_frame ();
4627 /* Prevent the instruction scheduler from
4628 moving instructions across the boundary. */
4629 emit_insn (gen_blockage ());
4631 /* If the function is 'naked', we do not have to generate
4632 epilogue code fragment BUT 'ret' instruction.
4633 However, if this function is also a variadic function,
4634 we need to create adjust stack pointer before 'ret' instruction. */
4635 if (cfun
->machine
->naked_p
)
4637 /* If this is a variadic function, we do not have to restore argument
4638 registers but need to adjust stack pointer back to previous stack
4639 frame location before return. */
4640 if (cfun
->machine
->va_args_size
!= 0)
4642 /* Generate sp adjustment instruction.
4643 We need to consider padding bytes here. */
4644 sp_adjust
= cfun
->machine
->va_args_size
4645 + cfun
->machine
->va_args_area_padding_bytes
;
4647 nds32_emit_adjust_frame (stack_pointer_rtx
,
4652 /* Generate return instruction by using 'return_internal' pattern.
4653 Make sure this instruction is after gen_blockage(). */
4655 emit_jump_insn (gen_return_internal ());
4659 if (frame_pointer_needed
)
4661 /* Restore fpu registers. */
4662 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4664 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4666 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4667 - (4 * callee-saved-registers)
4668 - (4 * exception-handling-data-registers)
4669 - (4 * callee-saved-gpr-registers padding byte)
4670 - (4 * callee-saved-fpr-registers)
4671 Note: we want to adjust stack pointer
4672 to the position for callee-saved fpr register,
4673 And restore fpu register use .bi instruction to adjust $sp
4674 from callee-saved fpr register to pop instruction. */
4675 sp_adjust
= cfun
->machine
->fp_size
4676 + cfun
->machine
->gp_size
4677 + cfun
->machine
->lp_size
4678 + cfun
->machine
->callee_saved_gpr_regs_size
4679 + cfun
->machine
->eh_return_data_regs_size
4680 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4681 + cfun
->machine
->callee_saved_fpr_regs_size
;
4683 nds32_emit_adjust_frame (stack_pointer_rtx
,
4684 hard_frame_pointer_rtx
,
4687 /* Emit fpu load instruction, using .bi instruction
4688 load fpu registers. */
4689 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4693 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4694 - (4 * callee-saved-registers)
4695 - (4 * exception-handling-data-registers)
4696 Note: No need to adjust
4697 cfun->machine->callee_saved_area_gpr_padding_bytes,
4698 because we want to adjust stack pointer
4699 to the position for pop instruction. */
4700 sp_adjust
= cfun
->machine
->fp_size
4701 + cfun
->machine
->gp_size
4702 + cfun
->machine
->lp_size
4703 + cfun
->machine
->callee_saved_gpr_regs_size
4704 + cfun
->machine
->eh_return_data_regs_size
;
4706 nds32_emit_adjust_frame (stack_pointer_rtx
,
4707 hard_frame_pointer_rtx
,
4713 /* Restore fpu registers. */
4714 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4716 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4718 /* Adjust $sp = $sp + local_size + out_args_size. */
4719 sp_adjust
= cfun
->machine
->local_size
4720 + cfun
->machine
->out_args_size
;
4722 nds32_emit_adjust_frame (stack_pointer_rtx
,
4726 /* Emit fpu load instruction, using .bi instruction
4727 load fpu registers, and adjust $sp from callee-saved fpr register
4728 to callee-saved gpr register. */
4729 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4733 /* If frame pointer is NOT needed,
4734 we cannot calculate the sp adjustment from frame pointer.
4735 Instead, we calculate the adjustment by local_size,
4736 out_args_size, and callee_saved_area_gpr_padding_bytes.
4737 Notice that such sp adjustment value may be out of range,
4738 so we have to deal with it as well. */
4740 /* Adjust $sp = $sp + local_size + out_args_size
4741 + callee_saved_area_gpr_padding_bytes. */
4742 sp_adjust
= cfun
->machine
->local_size
4743 + cfun
->machine
->out_args_size
4744 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4746 nds32_emit_adjust_frame (stack_pointer_rtx
,
4752 /* Restore eh data registers. */
4753 if (cfun
->machine
->use_eh_return_p
)
4755 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4756 Re
= cfun
->machine
->eh_return_data_last_regno
;
4758 /* No need to pop $fp, $gp, or $lp. */
4759 nds32_emit_stack_pop_multiple (Rb
, Re
, false, false, false);
4762 /* Get callee_first_regno and callee_last_regno. */
4763 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4764 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4766 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4767 to be saved, we don't have to create multiple pop instruction.
4768 Otherwise, a multiple pop instruction is needed. */
4769 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4770 && cfun
->machine
->fp_size
== 0
4771 && cfun
->machine
->gp_size
== 0
4772 && cfun
->machine
->lp_size
== 0))
4774 /* Create multiple pop instruction rtx. */
4775 nds32_emit_stack_pop_multiple (
4777 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
);
4780 /* If this is a variadic function, we do not have to restore argument
4781 registers but need to adjust stack pointer back to previous stack
4782 frame location before return. */
4783 if (cfun
->machine
->va_args_size
!= 0)
4785 /* Generate sp adjustment instruction.
4786 We need to consider padding bytes here. */
4787 sp_adjust
= cfun
->machine
->va_args_size
4788 + cfun
->machine
->va_args_area_padding_bytes
;
4790 nds32_emit_adjust_frame (stack_pointer_rtx
,
4795 /* If this function uses __builtin_eh_return, make stack adjustment
4796 for exception handler. */
4797 if (cfun
->machine
->use_eh_return_p
)
4799 /* We need to unwind the stack by the offset computed by
4800 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4801 based on SP. Ideally we would update the SP and define the
4802 CFA along the lines of:
4804 SP = SP + EH_RETURN_STACKADJ_RTX
4805 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4807 However the dwarf emitter only understands a constant
4810 The solution chosen here is to use the otherwise $ta ($r15)
4811 as a temporary register to hold the current SP value. The
4812 CFA is described using $ta then SP is modified. */
4817 ta_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
4819 insn
= emit_move_insn (ta_reg
, stack_pointer_rtx
);
4820 add_reg_note (insn
, REG_CFA_DEF_CFA
, ta_reg
);
4821 RTX_FRAME_RELATED_P (insn
) = 1;
4823 emit_insn (gen_addsi3 (stack_pointer_rtx
,
4825 EH_RETURN_STACKADJ_RTX
));
4827 /* Ensure the assignment to $ta does not get optimized away. */
4831 /* Generate return instruction. */
4833 emit_jump_insn (gen_return_internal ());
4836 /* Function for v3push prologue. */
4838 nds32_expand_prologue_v3push (void)
4845 /* Compute and setup stack frame size.
4846 The result will be in cfun->machine. */
4847 nds32_compute_stack_frame ();
4849 if (cfun
->machine
->callee_saved_gpr_regs_size
> 0)
4850 df_set_regs_ever_live (FP_REGNUM
, 1);
4852 /* If the function is 'naked',
4853 we do not have to generate prologue code fragment. */
4854 if (cfun
->machine
->naked_p
&& !flag_pic
)
4857 /* Get callee_first_regno and callee_last_regno. */
4858 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4859 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4861 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
4862 where imm8u has to be 8-byte alignment. */
4863 sp_adjust
= cfun
->machine
->local_size
4864 + cfun
->machine
->out_args_size
4865 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4866 + cfun
->machine
->callee_saved_fpr_regs_size
;
4868 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4869 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
4871 /* We can use 'push25 Re,imm8u'. */
4873 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4874 the pattern 'stack_v3push' is implemented in nds32.md. */
4875 nds32_emit_stack_v3push (Rb
, Re
, sp_adjust
);
4877 /* Save fpu registers. */
4878 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4880 /* Calculate fpr position. */
4881 int fpr_position
= cfun
->machine
->local_size
4882 + cfun
->machine
->out_args_size
;
4883 /* Emit fpu store instruction, using [$sp + offset] store
4885 nds32_emit_push_fpr_callee_saved (fpr_position
);
4888 /* Check frame_pointer_needed to see
4889 if we shall emit fp adjustment instruction. */
4890 if (frame_pointer_needed
)
4892 /* adjust $fp = $sp + 4 ($fp size)
4895 + (4 * n) (callee-saved registers)
4896 + sp_adjust ('push25 Re,imm8u')
4897 Note: Since we use 'push25 Re,imm8u',
4898 the position of stack pointer is further
4899 changed after push instruction.
4900 Hence, we need to take sp_adjust value
4901 into consideration. */
4902 fp_adjust
= cfun
->machine
->fp_size
4903 + cfun
->machine
->gp_size
4904 + cfun
->machine
->lp_size
4905 + cfun
->machine
->callee_saved_gpr_regs_size
4908 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4915 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4917 /* Calculate fpr space. */
4918 fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4919 + cfun
->machine
->callee_saved_fpr_regs_size
;
4921 /* We have to use 'push25 Re, fpr_space', to pre-allocate
4922 callee saved fpr registers space. */
4923 nds32_emit_stack_v3push (Rb
, Re
, fpr_space
);
4924 nds32_emit_push_fpr_callee_saved (0);
4928 /* We have to use 'push25 Re,0' and
4929 expand one more instruction to adjust $sp later. */
4931 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4932 the pattern 'stack_v3push' is implemented in nds32.md. */
4933 nds32_emit_stack_v3push (Rb
, Re
, 0);
4936 /* Check frame_pointer_needed to see
4937 if we shall emit fp adjustment instruction. */
4938 if (frame_pointer_needed
)
4940 /* adjust $fp = $sp + 4 ($fp size)
4943 + (4 * n) (callee-saved registers)
4944 Note: Since we use 'push25 Re,0',
4945 the stack pointer is just at the position
4946 after push instruction.
4947 No need to take sp_adjust into consideration. */
4948 fp_adjust
= cfun
->machine
->fp_size
4949 + cfun
->machine
->gp_size
4950 + cfun
->machine
->lp_size
4951 + cfun
->machine
->callee_saved_gpr_regs_size
;
4953 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4955 /* We use 'push25 Re, fpr_space', the $sp is
4956 on callee saved fpr position, so need to consider
4958 fp_adjust
= fp_adjust
+ fpr_space
;
4961 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4966 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4968 /* We use 'push25 Re, fpr_space',
4969 the $sp is on callee saved fpr position,
4970 no need to consider fpr space. */
4971 sp_adjust
= sp_adjust
- fpr_space
;
4974 /* Because we use 'push25 Re,0',
4975 we need to expand one more instruction to adjust $sp.
4976 using NEGATIVE value to tell that we are decreasing address. */
4977 nds32_emit_adjust_frame (stack_pointer_rtx
,
4982 /* Emit gp setup instructions for -fpic. */
4983 if (flag_pic
&& df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM
))
4984 nds32_emit_load_gp ();
4986 /* Prevent the instruction scheduler from
4987 moving instructions across the boundary. */
4988 emit_insn (gen_blockage ());
4991 /* Function for v3pop epilogue. */
4993 nds32_expand_epilogue_v3pop (bool sibcall_p
)
4998 /* Compute and setup stack frame size.
4999 The result will be in cfun->machine. */
5000 nds32_compute_stack_frame ();
5002 /* Prevent the instruction scheduler from
5003 moving instructions across the boundary. */
5004 emit_insn (gen_blockage ());
5006 /* If the function is 'naked', we do not have to generate
5007 epilogue code fragment BUT 'ret' instruction. */
5008 if (cfun
->machine
->naked_p
)
5010 /* Generate return instruction by using 'return_internal' pattern.
5011 Make sure this instruction is after gen_blockage(). */
5013 emit_jump_insn (gen_return_internal ());
5017 /* Get callee_first_regno and callee_last_regno. */
5018 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
5019 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
5021 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
5022 where imm8u has to be 8-byte alignment. */
5023 sp_adjust
= cfun
->machine
->local_size
5024 + cfun
->machine
->out_args_size
5025 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
5026 + cfun
->machine
->callee_saved_fpr_regs_size
;
5028 /* We have to consider alloca issue as well.
5029 If the function does call alloca(), the stack pointer is not fixed.
5030 In that case, we cannot use 'pop25 Re,imm8u' directly.
5031 We have to caculate stack pointer from frame pointer
5032 and then use 'pop25 Re,0'.
5033 Of course, the frame_pointer_needed should be nonzero
5034 if the function calls alloca(). */
5035 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
5036 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
5037 && !cfun
->calls_alloca
)
5039 /* Restore fpu registers. */
5040 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
5042 int fpr_position
= cfun
->machine
->local_size
5043 + cfun
->machine
->out_args_size
;
5044 /* Emit fpu load instruction, using [$sp + offset] restore
5046 nds32_emit_v3pop_fpr_callee_saved (fpr_position
);
5049 /* We can use 'pop25 Re,imm8u'. */
5051 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
5052 the pattern 'stack_v3pop' is implementad in nds32.md. */
5053 nds32_emit_stack_v3pop (Rb
, Re
, sp_adjust
);
5057 /* We have to use 'pop25 Re,0', and prior to it,
5058 we must expand one more instruction to adjust $sp. */
5060 if (frame_pointer_needed
)
5062 /* adjust $sp = $fp - 4 ($fp size)
5065 - (4 * n) (callee-saved registers)
5066 Note: No need to adjust
5067 cfun->machine->callee_saved_area_gpr_padding_bytes,
5068 because we want to adjust stack pointer
5069 to the position for pop instruction. */
5070 sp_adjust
= cfun
->machine
->fp_size
5071 + cfun
->machine
->gp_size
5072 + cfun
->machine
->lp_size
5073 + cfun
->machine
->callee_saved_gpr_regs_size
;
5075 /* Restore fpu registers. */
5076 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
5078 /* Set $sp to callee saved fpr position, we need to restore
5080 sp_adjust
= sp_adjust
5081 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
5082 + cfun
->machine
->callee_saved_fpr_regs_size
;
5084 nds32_emit_adjust_frame (stack_pointer_rtx
,
5085 hard_frame_pointer_rtx
,
5088 /* Emit fpu load instruction, using [$sp + offset] restore
5090 nds32_emit_v3pop_fpr_callee_saved (0);
5094 nds32_emit_adjust_frame (stack_pointer_rtx
,
5095 hard_frame_pointer_rtx
,
5101 /* If frame pointer is NOT needed,
5102 we cannot calculate the sp adjustment from frame pointer.
5103 Instead, we calculate the adjustment by local_size,
5104 out_args_size, and callee_saved_area_padding_bytes.
5105 Notice that such sp adjustment value may be out of range,
5106 so we have to deal with it as well. */
5108 /* Adjust $sp = $sp + local_size + out_args_size
5109 + callee_saved_area_gpr_padding_bytes
5110 + callee_saved_fpr_regs_size. */
5111 sp_adjust
= cfun
->machine
->local_size
5112 + cfun
->machine
->out_args_size
5113 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
5114 + cfun
->machine
->callee_saved_fpr_regs_size
;
5116 /* Restore fpu registers. */
5117 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
5119 /* Set $sp to callee saved fpr position, we need to restore
5121 sp_adjust
= sp_adjust
5122 - cfun
->machine
->callee_saved_area_gpr_padding_bytes
5123 - cfun
->machine
->callee_saved_fpr_regs_size
;
5125 nds32_emit_adjust_frame (stack_pointer_rtx
,
5129 /* Emit fpu load instruction, using [$sp + offset] restore
5131 nds32_emit_v3pop_fpr_callee_saved (0);
5135 /* sp_adjust value may be out of range of the addi instruction,
5136 create alternative add behavior with TA_REGNUM if necessary,
5137 using POSITIVE value to tell that we are increasing
5139 nds32_emit_adjust_frame (stack_pointer_rtx
,
5145 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
5147 /* We have fpr need to restore, so $sp is set on callee saved fpr
5148 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
5149 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
5150 + cfun
->machine
->callee_saved_fpr_regs_size
;
5151 nds32_emit_stack_v3pop (Rb
, Re
, fpr_space
);
5155 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
5156 the pattern 'stack_v3pop' is implementad in nds32.md. */
5157 nds32_emit_stack_v3pop (Rb
, Re
, 0);
5160 /* Generate return instruction. */
5161 emit_jump_insn (gen_pop25return ());
5164 /* Return nonzero if this function is known to have a null epilogue.
5165 This allows the optimizer to omit jumps to jumps if no stack
5168 nds32_can_use_return_insn (void)
5172 /* Prior to reloading, we can't tell how many registers must be saved.
5173 Thus we can not determine whether this function has null epilogue. */
5174 if (!reload_completed
)
5177 sp_adjust
= cfun
->machine
->local_size
5178 + cfun
->machine
->out_args_size
5179 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
5180 + cfun
->machine
->callee_saved_fpr_regs_size
;
5181 if (!cfun
->machine
->fp_as_gp_p
5182 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
5183 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
5184 && !cfun
->calls_alloca
5185 && NDS32_V3PUSH_AVAILABLE_P
5186 && !(TARGET_HARD_FLOAT
5187 && (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)))
5190 /* If no stack was created, two conditions must be satisfied:
5191 1. This is a naked function.
5192 So there is no callee-saved, local size, or outgoing size.
5193 2. This is NOT a variadic function.
5194 So there is no pushing arguement registers into the stack. */
5195 return (cfun
->machine
->naked_p
&& (cfun
->machine
->va_args_size
== 0));
5199 nds32_case_vector_shorten_mode (int min_offset
, int max_offset
,
5200 rtx body ATTRIBUTE_UNUSED
)
5202 if (min_offset
< 0 || max_offset
>= 0x2000)
5206 /* The jump table maybe need to 2 byte alignment,
5207 so reserved 1 byte for check max_offset. */
5208 if (max_offset
>= 0xff)
5215 /* ------------------------------------------------------------------------ */
5217 /* Return alignment for the label. */
5219 nds32_target_alignment (rtx_insn
*label
)
5223 if (!NDS32_ALIGN_P ())
5226 insn
= next_active_insn (label
);
5228 /* Always align to 4 byte when first instruction after label is jump
5229 instruction since length for that might changed, so let's always align
5230 it for make sure we don't lose any perfomance here. */
5232 || (get_attr_length (insn
) == 2
5233 && !JUMP_P (insn
) && !CALL_P (insn
)))
5239 /* Return alignment for data. */
5241 nds32_data_alignment (tree data
,
5242 unsigned int basic_align
)
5244 if ((basic_align
< BITS_PER_WORD
)
5245 && (TREE_CODE (data
) == ARRAY_TYPE
5246 || TREE_CODE (data
) == UNION_TYPE
5247 || TREE_CODE (data
) == RECORD_TYPE
))
5248 return BITS_PER_WORD
;
5253 /* Return alignment for constant value. */
5254 static HOST_WIDE_INT
5255 nds32_constant_alignment (const_tree constant
,
5256 HOST_WIDE_INT basic_align
)
5258 /* Make string literal and constant for constructor to word align. */
5259 if (((TREE_CODE (constant
) == STRING_CST
5260 || TREE_CODE (constant
) == CONSTRUCTOR
5261 || TREE_CODE (constant
) == UNION_TYPE
5262 || TREE_CODE (constant
) == RECORD_TYPE
5263 || TREE_CODE (constant
) == ARRAY_TYPE
)
5264 && basic_align
< BITS_PER_WORD
))
5265 return BITS_PER_WORD
;
5270 /* Return alignment for local variable. */
5272 nds32_local_alignment (tree local ATTRIBUTE_UNUSED
,
5273 unsigned int basic_align
)
5275 bool at_least_align_to_word
= false;
5276 /* Make local array, struct and union at least align to word for make
5277 sure it can unroll memcpy when initialize by constant. */
5278 switch (TREE_CODE (local
))
5283 at_least_align_to_word
= true;
5286 at_least_align_to_word
= false;
5289 if (at_least_align_to_word
5290 && (basic_align
< BITS_PER_WORD
))
5291 return BITS_PER_WORD
;
5297 nds32_split_double_word_load_store_p(rtx
*operands
, bool load_p
)
5299 rtx mem
= load_p
? operands
[1] : operands
[0];
5300 /* Do split at split2 if -O0 or schedule 2 not enable. */
5301 if (optimize
== 0 || !flag_schedule_insns_after_reload
)
5302 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
5304 /* Split double word load store after copy propgation. */
5305 if (current_pass
== NULL
)
5308 const char *pass_name
= current_pass
->name
;
5309 if (pass_name
&& ((strcmp (pass_name
, "split4") == 0)
5310 || (strcmp (pass_name
, "split5") == 0)))
5311 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
5317 nds32_use_blocks_for_constant_p (machine_mode mode
,
5318 const_rtx x ATTRIBUTE_UNUSED
)
5320 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
5321 && (mode
== DFmode
|| mode
== SFmode
))
5327 /* ------------------------------------------------------------------------ */
5329 /* PART 5: Initialize target hook structure and definitions. */
5331 /* Controlling the Compilation Driver. */
5334 /* Run-time Target Specification. */
5337 /* Defining Data Structures for Per-function Information. */
5340 /* Storage Layout. */
5342 #undef TARGET_PROMOTE_FUNCTION_MODE
5343 #define TARGET_PROMOTE_FUNCTION_MODE \
5344 default_promote_function_mode_always_promote
5346 #undef TARGET_EXPAND_TO_RTL_HOOK
5347 #define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
5349 #undef TARGET_CONSTANT_ALIGNMENT
5350 #define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment
5353 /* Layout of Source Language Data Types. */
5356 /* Register Usage. */
5358 /* -- Basic Characteristics of Registers. */
5360 #undef TARGET_CONDITIONAL_REGISTER_USAGE
5361 #define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
5363 /* -- Order of Allocation of Registers. */
5365 /* -- How Values Fit in Registers. */
5367 #undef TARGET_HARD_REGNO_NREGS
5368 #define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
5370 #undef TARGET_HARD_REGNO_MODE_OK
5371 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
5373 #undef TARGET_MODES_TIEABLE_P
5374 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
5376 /* -- Handling Leaf Functions. */
5378 /* -- Registers That Form a Stack. */
5381 /* Register Classes. */
5383 #undef TARGET_CLASS_MAX_NREGS
5384 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
5386 #undef TARGET_REGISTER_PRIORITY
5387 #define TARGET_REGISTER_PRIORITY nds32_register_priority
5389 #undef TARGET_CAN_CHANGE_MODE_CLASS
5390 #define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
5393 /* Obsolete Macros for Defining Constraints. */
5396 /* Stack Layout and Calling Conventions. */
5398 /* -- Basic Stack Layout. */
5400 /* -- Exception Handling Support. */
5402 /* -- Specifying How Stack Checking is Done. */
5404 /* -- Registers That Address the Stack Frame. */
5406 /* -- Eliminating Frame Pointer and Arg Pointer. */
5408 #undef TARGET_CAN_ELIMINATE
5409 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
5411 /* -- Passing Function Arguments on the Stack. */
5413 /* -- Passing Arguments in Registers. */
5415 #undef TARGET_FUNCTION_ARG
5416 #define TARGET_FUNCTION_ARG nds32_function_arg
5418 #undef TARGET_MUST_PASS_IN_STACK
5419 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
5421 #undef TARGET_ARG_PARTIAL_BYTES
5422 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
5424 #undef TARGET_FUNCTION_ARG_ADVANCE
5425 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5427 #undef TARGET_FUNCTION_ARG_BOUNDARY
5428 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5430 #undef TARGET_VECTOR_MODE_SUPPORTED_P
5431 #define TARGET_VECTOR_MODE_SUPPORTED_P nds32_vector_mode_supported_p
5433 /* -- How Scalar Function Values Are Returned. */
5435 #undef TARGET_FUNCTION_VALUE
5436 #define TARGET_FUNCTION_VALUE nds32_function_value
5438 #undef TARGET_LIBCALL_VALUE
5439 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5441 #undef TARGET_FUNCTION_VALUE_REGNO_P
5442 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5444 /* -- How Large Values Are Returned. */
5446 #undef TARGET_RETURN_IN_MEMORY
5447 #define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
5449 /* -- Caller-Saves Register Allocation. */
5451 /* -- Function Entry and Exit. */
5453 #undef TARGET_ASM_FUNCTION_PROLOGUE
5454 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5456 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5457 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5459 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5460 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5462 #undef TARGET_ASM_FUNCTION_EPILOGUE
5463 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5465 #undef TARGET_ASM_OUTPUT_MI_THUNK
5466 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5468 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5469 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5471 /* -- Generating Code for Profiling. */
5473 /* -- Permitting tail calls. */
5475 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5476 #define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
5478 #undef TARGET_WARN_FUNC_RETURN
5479 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5481 /* Stack smashing protection. */
5484 /* Implementing the Varargs Macros. */
5486 #undef TARGET_SETUP_INCOMING_VARARGS
5487 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5489 #undef TARGET_STRICT_ARGUMENT_NAMING
5490 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5493 /* Trampolines for Nested Functions. */
5495 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5496 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5498 #undef TARGET_TRAMPOLINE_INIT
5499 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5502 /* Implicit Calls to Library Routines. */
5505 /* Addressing Modes. */
5507 #undef TARGET_LEGITIMATE_ADDRESS_P
5508 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5510 #undef TARGET_LEGITIMIZE_ADDRESS
5511 #define TARGET_LEGITIMIZE_ADDRESS nds32_legitimize_address
5513 #undef TARGET_LEGITIMATE_CONSTANT_P
5514 #define TARGET_LEGITIMATE_CONSTANT_P nds32_legitimate_constant_p
5516 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
5517 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE nds32_vectorize_preferred_simd_mode
5519 #undef TARGET_CANNOT_FORCE_CONST_MEM
5520 #define TARGET_CANNOT_FORCE_CONST_MEM nds32_cannot_force_const_mem
5522 #undef TARGET_DELEGITIMIZE_ADDRESS
5523 #define TARGET_DELEGITIMIZE_ADDRESS nds32_delegitimize_address
5526 /* Anchored Addresses. */
5529 /* Condition Code Status. */
5531 /* -- Representation of condition codes using (cc0). */
5533 /* -- Representation of condition codes using registers. */
5535 #undef TARGET_CANONICALIZE_COMPARISON
5536 #define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5538 /* -- Macros to control conditional execution. */
5541 /* Describing Relative Costs of Operations. */
5543 #undef TARGET_REGISTER_MOVE_COST
5544 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5546 #undef TARGET_MEMORY_MOVE_COST
5547 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5549 #undef TARGET_RTX_COSTS
5550 #define TARGET_RTX_COSTS nds32_rtx_costs
5552 #undef TARGET_ADDRESS_COST
5553 #define TARGET_ADDRESS_COST nds32_address_cost
5556 /* Adjusting the Instruction Scheduler. */
5559 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5561 #undef TARGET_ENCODE_SECTION_INFO
5562 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5565 /* Position Independent Code. */
5568 /* Defining the Output Assembler Language. */
5570 /* -- The Overall Framework of an Assembler File. */
5572 #undef TARGET_ASM_FILE_START
5573 #define TARGET_ASM_FILE_START nds32_asm_file_start
5574 #undef TARGET_ASM_FILE_END
5575 #define TARGET_ASM_FILE_END nds32_asm_file_end
5577 /* -- Output of Data. */
5579 #undef TARGET_ASM_ALIGNED_HI_OP
5580 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5582 #undef TARGET_ASM_ALIGNED_SI_OP
5583 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5585 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
5586 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA nds32_asm_output_addr_const_extra
5588 /* -- Output of Uninitialized Variables. */
5590 /* -- Output and Generation of Labels. */
5592 #undef TARGET_ASM_GLOBALIZE_LABEL
5593 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5595 /* -- How Initialization Functions Are Handled. */
5597 /* -- Macros Controlling Initialization Routines. */
5599 /* -- Output of Assembler Instructions. */
5601 #undef TARGET_PRINT_OPERAND
5602 #define TARGET_PRINT_OPERAND nds32_print_operand
5603 #undef TARGET_PRINT_OPERAND_ADDRESS
5604 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5606 /* -- Output of Dispatch Tables. */
5608 /* -- Assembler Commands for Exception Regions. */
5610 #undef TARGET_DWARF_REGISTER_SPAN
5611 #define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5613 /* -- Assembler Commands for Alignment. */
5616 /* Controlling Debugging Information Format. */
5618 /* -- Macros Affecting All Debugging Formats. */
5620 /* -- Specific Options for DBX Output. */
5622 /* -- Open-Ended Hooks for DBX Format. */
5624 /* -- File Names in DBX Format. */
5626 /* -- Macros for DWARF Output. */
5628 /* -- Macros for VMS Debug Format. */
5631 /* Cross Compilation and Floating Point. */
5634 /* Mode Switching Instructions. */
5637 /* Defining target-specific uses of __attribute__. */
5639 #undef TARGET_ATTRIBUTE_TABLE
5640 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5642 #undef TARGET_MERGE_DECL_ATTRIBUTES
5643 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5645 #undef TARGET_INSERT_ATTRIBUTES
5646 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5648 #undef TARGET_OPTION_PRAGMA_PARSE
5649 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5651 #undef TARGET_OPTION_OVERRIDE
5652 #define TARGET_OPTION_OVERRIDE nds32_option_override
5655 /* Emulating TLS. */
5658 /* Defining coprocessor specifics for MIPS targets. */
5661 /* Parameters for Precompiled Header Validity Checking. */
5664 /* C++ ABI parameters. */
5667 /* Adding support for named address spaces. */
5670 /* Miscellaneous Parameters. */
5672 #undef TARGET_MD_ASM_ADJUST
5673 #define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5675 #undef TARGET_INIT_BUILTINS
5676 #define TARGET_INIT_BUILTINS nds32_init_builtins
5678 #undef TARGET_BUILTIN_DECL
5679 #define TARGET_BUILTIN_DECL nds32_builtin_decl
5681 #undef TARGET_EXPAND_BUILTIN
5682 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5685 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5686 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5689 /* ------------------------------------------------------------------------ */
5691 /* Initialize the GCC target structure. */
5693 struct gcc_target targetm
= TARGET_INITIALIZER
;
5695 /* ------------------------------------------------------------------------ */