1 /* Subroutines used for code generation of Andes NDS32 cpu for GNU compiler
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* ------------------------------------------------------------------------ */
23 #define IN_TARGET_CODE 1
27 #include "coretypes.h"
32 #include "tree-pass.h"
33 #include "stringpool.h"
38 #include "optabs.h" /* For GEN_FCN. */
42 #include "diagnostic-core.h"
43 #include "stor-layout.h"
49 #include "tm-constrs.h"
54 /* This file should be included last. */
55 #include "target-def.h"
57 /* ------------------------------------------------------------------------ */
59 /* This file is divided into five parts:
61 PART 1: Auxiliary static variable definitions and
62 target hook static variable definitions.
64 PART 2: Auxiliary static function definitions.
66 PART 3: Implement target hook stuff definitions.
68 PART 4: Implemet extern function definitions,
69 the prototype is in nds32-protos.h.
71 PART 5: Initialize target hook structure and definitions. */
73 /* ------------------------------------------------------------------------ */
75 /* PART 1: Auxiliary static variable definitions and
76 target hook static variable definitions. */
78 /* Define intrinsic register names.
79 Please refer to nds32_intrinsic.h file, the index is corresponding to
80 'enum nds32_intrinsic_registers' data type values.
81 NOTE that the base value starting from 1024. */
82 static const char * const nds32_intrinsic_register_names
[] =
240 /* Define instrinsic cctl names. */
241 static const char * const nds32_cctl_names
[] =
269 static const char * const nds32_dpref_names
[] =
279 /* Defining register allocation order for performance.
280 We want to allocate callee-saved registers after others.
281 It may be used by nds32_adjust_reg_alloc_order(). */
282 static const int nds32_reg_alloc_order_for_speed
[] =
284 0, 1, 2, 3, 4, 5, 16, 17,
285 18, 19, 20, 21, 22, 23, 24, 25,
286 26, 27, 6, 7, 8, 9, 10, 11,
290 /* Defining target-specific uses of __attribute__. */
291 static const struct attribute_spec nds32_attribute_table
[] =
293 /* Syntax: { name, min_len, max_len, decl_required, type_required,
294 function_type_required, affects_type_identity, handler,
297 /* The interrupt vid: [0-63]+ (actual vector number starts from 9 to 72). */
298 { "interrupt", 1, 64, false, false, false, false, NULL
, NULL
},
299 /* The exception vid: [1-8]+ (actual vector number starts from 1 to 8). */
300 { "exception", 1, 8, false, false, false, false, NULL
, NULL
},
301 /* Argument is user's interrupt numbers. The vector number is always 0. */
302 { "reset", 1, 1, false, false, false, false, NULL
, NULL
},
304 /* The attributes describing isr nested type. */
305 { "nested", 0, 0, false, false, false, false, NULL
, NULL
},
306 { "not_nested", 0, 0, false, false, false, false, NULL
, NULL
},
307 { "nested_ready", 0, 0, false, false, false, false, NULL
, NULL
},
309 /* The attributes describing isr register save scheme. */
310 { "save_all", 0, 0, false, false, false, false, NULL
, NULL
},
311 { "partial_save", 0, 0, false, false, false, false, NULL
, NULL
},
313 /* The attributes used by reset attribute. */
314 { "nmi", 1, 1, false, false, false, false, NULL
, NULL
},
315 { "warm", 1, 1, false, false, false, false, NULL
, NULL
},
317 /* The attribute telling no prologue/epilogue. */
318 { "naked", 0, 0, false, false, false, false, NULL
, NULL
},
320 /* The last attribute spec is set to be NULL. */
321 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
325 /* ------------------------------------------------------------------------ */
327 /* PART 2: Auxiliary static function definitions. */
329 /* Function to save and restore machine-specific function data. */
330 static struct machine_function
*
331 nds32_init_machine_status (void)
333 struct machine_function
*machine
;
334 machine
= ggc_cleared_alloc
<machine_function
> ();
336 /* Initially assume this function does not use __builtin_eh_return. */
337 machine
->use_eh_return_p
= 0;
339 /* Initially assume this function needs prologue/epilogue. */
340 machine
->naked_p
= 0;
342 /* Initially assume this function does NOT use fp_as_gp optimization. */
343 machine
->fp_as_gp_p
= 0;
345 /* Initially this function is not under strictly aligned situation. */
346 machine
->strict_aligned_p
= 0;
351 /* Function to compute stack frame size and
352 store into cfun->machine structure. */
354 nds32_compute_stack_frame (void)
360 /* Because nds32_compute_stack_frame() will be called from different place,
361 everytime we enter this function, we have to assume this function
362 needs prologue/epilogue. */
363 cfun
->machine
->naked_p
= 0;
366 /* If __builtin_eh_return is used, we better have frame pointer needed
367 so that we can easily locate the stack slot of return address. */
368 if (crtl
->calls_eh_return
)
370 frame_pointer_needed
= 1;
372 /* We need to mark eh data registers that need to be saved
374 cfun
->machine
->eh_return_data_first_regno
= EH_RETURN_DATA_REGNO (0);
375 for (r
= 0; EH_RETURN_DATA_REGNO (r
) != INVALID_REGNUM
; r
++)
376 cfun
->machine
->eh_return_data_last_regno
= r
;
378 cfun
->machine
->eh_return_data_regs_size
379 = 4 * (cfun
->machine
->eh_return_data_last_regno
380 - cfun
->machine
->eh_return_data_first_regno
382 cfun
->machine
->use_eh_return_p
= 1;
386 /* Assigning SP_REGNUM to eh_first_regno and eh_last_regno means we
387 do not need to handle __builtin_eh_return case in this function. */
388 cfun
->machine
->eh_return_data_first_regno
= SP_REGNUM
;
389 cfun
->machine
->eh_return_data_last_regno
= SP_REGNUM
;
391 cfun
->machine
->eh_return_data_regs_size
= 0;
392 cfun
->machine
->use_eh_return_p
= 0;
395 /* Get variadic arguments size to prepare pretend arguments and
396 we will push them into stack at prologue by ourself. */
397 cfun
->machine
->va_args_size
= crtl
->args
.pretend_args_size
;
398 if (cfun
->machine
->va_args_size
!= 0)
400 cfun
->machine
->va_args_first_regno
401 = NDS32_GPR_ARG_FIRST_REGNUM
402 + NDS32_MAX_GPR_REGS_FOR_ARGS
403 - (crtl
->args
.pretend_args_size
/ UNITS_PER_WORD
);
404 cfun
->machine
->va_args_last_regno
405 = NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
- 1;
409 cfun
->machine
->va_args_first_regno
= SP_REGNUM
;
410 cfun
->machine
->va_args_last_regno
= SP_REGNUM
;
413 /* Important: We need to make sure that varargs area is 8-byte alignment. */
414 block_size
= cfun
->machine
->va_args_size
;
415 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
417 cfun
->machine
->va_args_area_padding_bytes
418 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
421 /* Get local variables, incoming variables, and temporary variables size.
422 Note that we need to make sure it is 8-byte alignment because
423 there may be no padding bytes if we are using LRA. */
424 cfun
->machine
->local_size
= NDS32_ROUND_UP_DOUBLE_WORD (get_frame_size ());
426 /* Get outgoing arguments size. */
427 cfun
->machine
->out_args_size
= crtl
->outgoing_args_size
;
429 /* If $fp value is required to be saved on stack, it needs 4 bytes space.
430 Check whether $fp is ever live. */
431 cfun
->machine
->fp_size
= (df_regs_ever_live_p (FP_REGNUM
)) ? 4 : 0;
433 /* If $gp value is required to be saved on stack, it needs 4 bytes space.
434 Check whether we are using PIC code genration. */
435 cfun
->machine
->gp_size
= (flag_pic
) ? 4 : 0;
437 /* If $lp value is required to be saved on stack, it needs 4 bytes space.
438 Check whether $lp is ever live. */
439 cfun
->machine
->lp_size
= (df_regs_ever_live_p (LP_REGNUM
)) ? 4 : 0;
441 /* Initially there is no padding bytes. */
442 cfun
->machine
->callee_saved_area_gpr_padding_bytes
= 0;
444 /* Calculate the bytes of saving callee-saved registers on stack. */
445 cfun
->machine
->callee_saved_gpr_regs_size
= 0;
446 cfun
->machine
->callee_saved_first_gpr_regno
= SP_REGNUM
;
447 cfun
->machine
->callee_saved_last_gpr_regno
= SP_REGNUM
;
448 cfun
->machine
->callee_saved_fpr_regs_size
= 0;
449 cfun
->machine
->callee_saved_first_fpr_regno
= SP_REGNUM
;
450 cfun
->machine
->callee_saved_last_fpr_regno
= SP_REGNUM
;
452 /* Currently, there is no need to check $r28~$r31
453 because we will save them in another way. */
454 for (r
= 0; r
< 28; r
++)
456 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
458 /* Mark the first required callee-saved register
459 (only need to set it once).
460 If first regno == SP_REGNUM, we can tell that
461 it is the first time to be here. */
462 if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
463 cfun
->machine
->callee_saved_first_gpr_regno
= r
;
464 /* Mark the last required callee-saved register. */
465 cfun
->machine
->callee_saved_last_gpr_regno
= r
;
469 /* Recording fpu callee-saved register. */
470 if (TARGET_HARD_FLOAT
)
472 for (r
= NDS32_FIRST_FPR_REGNUM
; r
< NDS32_LAST_FPR_REGNUM
; r
++)
474 if (NDS32_REQUIRED_CALLEE_SAVED_P (r
))
476 /* Mark the first required callee-saved register. */
477 if (cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
)
479 /* Make first callee-saved number is even,
480 bacause we use doubleword access, and this way
481 promise 8-byte alignemt. */
482 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (r
))
483 cfun
->machine
->callee_saved_first_fpr_regno
= r
- 1;
485 cfun
->machine
->callee_saved_first_fpr_regno
= r
;
487 cfun
->machine
->callee_saved_last_fpr_regno
= r
;
491 /* Make last callee-saved register number is odd,
492 we hope callee-saved register is even. */
493 int last_fpr
= cfun
->machine
->callee_saved_last_fpr_regno
;
494 if (NDS32_FPR_REGNO_OK_FOR_DOUBLE (last_fpr
))
495 cfun
->machine
->callee_saved_last_fpr_regno
++;
498 /* Check if this function can omit prologue/epilogue code fragment.
499 If there is 'naked' attribute in this function,
500 we can set 'naked_p' flag to indicate that
501 we do not have to generate prologue/epilogue.
502 Or, if all the following conditions succeed,
503 we can set this function 'naked_p' as well:
504 condition 1: first_regno == last_regno == SP_REGNUM,
505 which means we do not have to save
506 any callee-saved registers.
507 condition 2: Both $lp and $fp are NOT live in this function,
508 which means we do not need to save them and there
510 condition 3: There is no local_size, which means
511 we do not need to adjust $sp. */
512 if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl
))
513 || (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
514 && cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
515 && cfun
->machine
->callee_saved_first_fpr_regno
== SP_REGNUM
516 && cfun
->machine
->callee_saved_last_fpr_regno
== SP_REGNUM
517 && !df_regs_ever_live_p (FP_REGNUM
)
518 && !df_regs_ever_live_p (LP_REGNUM
)
519 && cfun
->machine
->local_size
== 0))
521 /* Set this function 'naked_p' and other functions can check this flag.
522 Note that in nds32 port, the 'naked_p = 1' JUST means there is no
523 callee-saved, local size, and outgoing size.
524 The varargs space and ret instruction may still present in
525 the prologue/epilogue expanding. */
526 cfun
->machine
->naked_p
= 1;
528 /* No need to save $fp, $gp, and $lp.
529 We should set these value to be zero
530 so that nds32_initial_elimination_offset() can work properly. */
531 cfun
->machine
->fp_size
= 0;
532 cfun
->machine
->gp_size
= 0;
533 cfun
->machine
->lp_size
= 0;
535 /* If stack usage computation is required,
536 we need to provide the static stack size. */
537 if (flag_stack_usage_info
)
538 current_function_static_stack_size
= 0;
540 /* No need to do following adjustment, return immediately. */
544 v3pushpop_p
= NDS32_V3PUSH_AVAILABLE_P
;
546 /* Adjustment for v3push instructions:
547 If we are using v3push (push25/pop25) instructions,
548 we need to make sure Rb is $r6 and Re is
549 located on $r6, $r8, $r10, or $r14.
550 Some results above will be discarded and recomputed.
551 Note that it is only available under V3/V3M ISA and we
552 DO NOT setup following stuff for isr or variadic function. */
556 cfun->machine->fp_size
557 cfun->machine->gp_size
558 cfun->machine->lp_size
559 cfun->machine->callee_saved_first_gpr_regno
560 cfun->machine->callee_saved_last_gpr_regno */
562 /* For v3push instructions, $fp, $gp, and $lp are always saved. */
563 cfun
->machine
->fp_size
= 4;
564 cfun
->machine
->gp_size
= 4;
565 cfun
->machine
->lp_size
= 4;
567 /* Remember to set Rb = $r6. */
568 cfun
->machine
->callee_saved_first_gpr_regno
= 6;
570 if (cfun
->machine
->callee_saved_last_gpr_regno
<= 6)
573 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
575 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 8)
578 cfun
->machine
->callee_saved_last_gpr_regno
= 8;
580 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 10)
583 cfun
->machine
->callee_saved_last_gpr_regno
= 10;
585 else if (cfun
->machine
->callee_saved_last_gpr_regno
<= 14)
588 cfun
->machine
->callee_saved_last_gpr_regno
= 14;
590 else if (cfun
->machine
->callee_saved_last_gpr_regno
== SP_REGNUM
)
592 /* If last_regno is SP_REGNUM, which means
593 it is never changed, so set it to Re = $r6. */
594 cfun
->machine
->callee_saved_last_gpr_regno
= 6;
598 /* The program flow should not go here. */
603 int sp_adjust
= cfun
->machine
->local_size
604 + cfun
->machine
->out_args_size
605 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
606 + cfun
->machine
->callee_saved_fpr_regs_size
;
610 && !frame_pointer_needed
)
612 block_size
= cfun
->machine
->fp_size
613 + cfun
->machine
->gp_size
614 + cfun
->machine
->lp_size
;
616 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
617 block_size
+= (4 * (cfun
->machine
->callee_saved_last_gpr_regno
618 - cfun
->machine
->callee_saved_first_gpr_regno
621 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
623 /* $r14 is last callee save register. */
624 if (cfun
->machine
->callee_saved_last_gpr_regno
625 < NDS32_LAST_CALLEE_SAVE_GPR_REGNUM
)
627 cfun
->machine
->callee_saved_last_gpr_regno
++;
629 else if (cfun
->machine
->callee_saved_first_gpr_regno
== SP_REGNUM
)
631 cfun
->machine
->callee_saved_first_gpr_regno
632 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
633 cfun
->machine
->callee_saved_last_gpr_regno
634 = NDS32_FIRST_CALLEE_SAVE_GPR_REGNUM
;
639 /* We have correctly set callee_saved_first_gpr_regno
640 and callee_saved_last_gpr_regno.
641 Initially, the callee_saved_gpr_regs_size is supposed to be 0.
642 As long as callee_saved_last_gpr_regno is not SP_REGNUM,
643 we can update callee_saved_gpr_regs_size with new size. */
644 if (cfun
->machine
->callee_saved_last_gpr_regno
!= SP_REGNUM
)
646 /* Compute pushed size of callee-saved registers. */
647 cfun
->machine
->callee_saved_gpr_regs_size
648 = 4 * (cfun
->machine
->callee_saved_last_gpr_regno
649 - cfun
->machine
->callee_saved_first_gpr_regno
653 if (TARGET_HARD_FLOAT
)
655 /* Compute size of callee svaed floating-point registers. */
656 if (cfun
->machine
->callee_saved_last_fpr_regno
!= SP_REGNUM
)
658 cfun
->machine
->callee_saved_fpr_regs_size
659 = 4 * (cfun
->machine
->callee_saved_last_fpr_regno
660 - cfun
->machine
->callee_saved_first_fpr_regno
665 /* Important: We need to make sure that
666 (fp_size + gp_size + lp_size + callee_saved_gpr_regs_size)
668 If it is not, calculate the padding bytes. */
669 block_size
= cfun
->machine
->fp_size
670 + cfun
->machine
->gp_size
671 + cfun
->machine
->lp_size
672 + cfun
->machine
->callee_saved_gpr_regs_size
;
673 if (!NDS32_DOUBLE_WORD_ALIGN_P (block_size
))
675 cfun
->machine
->callee_saved_area_gpr_padding_bytes
676 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
) - block_size
;
679 /* If stack usage computation is required,
680 we need to provide the static stack size. */
681 if (flag_stack_usage_info
)
683 current_function_static_stack_size
684 = NDS32_ROUND_UP_DOUBLE_WORD (block_size
)
685 + cfun
->machine
->local_size
686 + cfun
->machine
->out_args_size
;
690 /* Function to create a parallel rtx pattern
691 which presents stack push multiple behavior.
692 The overall concept are:
693 "push registers to memory",
694 "adjust stack pointer". */
696 nds32_emit_stack_push_multiple (unsigned Rb
, unsigned Re
,
697 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
,
713 /* We need to provide a customized rtx which contains
714 necessary information for data analysis,
715 so we create a parallel rtx like this:
716 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
718 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
721 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
723 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
725 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
727 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
729 (set (reg:SI SP_REGNUM)
730 (plus (reg:SI SP_REGNUM) (const_int -32)))]) */
732 /* Calculate the number of registers that will be pushed. */
740 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
741 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
742 num_use_regs
= extra_count
;
744 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
746 /* In addition to used registers,
747 we need one more space for (set sp sp-x) rtx. */
748 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
749 rtvec_alloc (num_use_regs
+ 1));
752 /* Initialize offset and start to create push behavior. */
753 offset
= -(num_use_regs
* 4);
755 /* Create (set mem regX) from Rb, Rb+1 up to Re. */
756 for (regno
= Rb
; regno
<= Re
; regno
++)
758 /* Rb and Re may be SP_REGNUM.
759 We need to break this loop immediately. */
760 if (regno
== SP_REGNUM
)
763 reg
= gen_rtx_REG (SImode
, regno
);
764 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
767 push_rtx
= gen_rtx_SET (mem
, reg
);
768 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
769 RTX_FRAME_RELATED_P (push_rtx
) = 1;
774 /* Create (set mem fp), (set mem gp), and (set mem lp) if necessary. */
777 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
778 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
781 push_rtx
= gen_rtx_SET (mem
, reg
);
782 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
783 RTX_FRAME_RELATED_P (push_rtx
) = 1;
789 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
790 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
793 push_rtx
= gen_rtx_SET (mem
, reg
);
794 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
795 RTX_FRAME_RELATED_P (push_rtx
) = 1;
801 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
802 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
805 push_rtx
= gen_rtx_SET (mem
, reg
);
806 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
807 RTX_FRAME_RELATED_P (push_rtx
) = 1;
812 /* Create (set sp sp-x). */
814 /* We need to re-calculate the offset value again for adjustment. */
815 offset
= -(num_use_regs
* 4);
817 = gen_rtx_SET (stack_pointer_rtx
,
818 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
819 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
820 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
822 parallel_insn
= emit_insn (parallel_insn
);
824 /* The insn rtx 'parallel_insn' will change frame layout.
825 We need to use RTX_FRAME_RELATED_P so that GCC is able to
826 generate CFI (Call Frame Information) stuff. */
827 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
829 /* Don't use GCC's logic for CFI info if we are generate a push for VAARG
830 since we will not restore those register at epilogue. */
833 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
834 copy_rtx (adjust_sp_rtx
), NULL_RTX
);
835 REG_NOTES (parallel_insn
) = dwarf
;
839 /* Function to create a parallel rtx pattern
840 which presents stack pop multiple behavior.
841 The overall concept are:
842 "pop registers from memory",
843 "adjust stack pointer". */
845 nds32_emit_stack_pop_multiple (unsigned Rb
, unsigned Re
,
846 bool save_fp_p
, bool save_gp_p
, bool save_lp_p
)
859 rtx dwarf
= NULL_RTX
;
861 /* We need to provide a customized rtx which contains
862 necessary information for data analysis,
863 so we create a parallel rtx like this:
864 (parallel [(set (reg:SI Rb)
865 (mem (reg:SI SP_REGNUM)))
867 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
870 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
871 (set (reg:SI FP_REGNUM)
872 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
873 (set (reg:SI GP_REGNUM)
874 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
875 (set (reg:SI LP_REGNUM)
876 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
877 (set (reg:SI SP_REGNUM)
878 (plus (reg:SI SP_REGNUM) (const_int 32)))]) */
880 /* Calculate the number of registers that will be poped. */
888 /* Note that Rb and Re may be SP_REGNUM. DO NOT count it in. */
889 if (Rb
== SP_REGNUM
&& Re
== SP_REGNUM
)
890 num_use_regs
= extra_count
;
892 num_use_regs
= Re
- Rb
+ 1 + extra_count
;
894 /* In addition to used registers,
895 we need one more space for (set sp sp+x) rtx. */
896 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
897 rtvec_alloc (num_use_regs
+ 1));
900 /* Initialize offset and start to create pop behavior. */
903 /* Create (set regX mem) from Rb, Rb+1 up to Re. */
904 for (regno
= Rb
; regno
<= Re
; regno
++)
906 /* Rb and Re may be SP_REGNUM.
907 We need to break this loop immediately. */
908 if (regno
== SP_REGNUM
)
911 reg
= gen_rtx_REG (SImode
, regno
);
912 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
915 pop_rtx
= gen_rtx_SET (reg
, mem
);
916 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
917 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
921 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
924 /* Create (set fp mem), (set gp mem), and (set lp mem) if necessary. */
927 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
928 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
931 pop_rtx
= gen_rtx_SET (reg
, mem
);
932 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
933 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
937 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
941 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
942 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
945 pop_rtx
= gen_rtx_SET (reg
, mem
);
946 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
947 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
951 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
955 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
956 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
959 pop_rtx
= gen_rtx_SET (reg
, mem
);
960 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
961 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
965 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
968 /* Create (set sp sp+x). */
970 /* The offset value is already in place. No need to re-calculate it. */
972 = gen_rtx_SET (stack_pointer_rtx
,
973 plus_constant (Pmode
, stack_pointer_rtx
, offset
));
974 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
976 /* Tell gcc we adjust SP in this insn. */
977 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
, copy_rtx (adjust_sp_rtx
), dwarf
);
979 parallel_insn
= emit_insn (parallel_insn
);
981 /* The insn rtx 'parallel_insn' will change frame layout.
982 We need to use RTX_FRAME_RELATED_P so that GCC is able to
983 generate CFI (Call Frame Information) stuff. */
984 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
986 /* Add CFI info by manual. */
987 REG_NOTES (parallel_insn
) = dwarf
;
990 /* Function to create a parallel rtx pattern
991 which presents stack v3push behavior.
992 The overall concept are:
993 "push registers to memory",
994 "adjust stack pointer". */
996 nds32_emit_stack_v3push (unsigned Rb
,
1011 /* We need to provide a customized rtx which contains
1012 necessary information for data analysis,
1013 so we create a parallel rtx like this:
1014 (parallel [(set (mem (plus (reg:SI SP_REGNUM) (const_int -32)))
1016 (set (mem (plus (reg:SI SP_REGNUM) (const_int -28)))
1019 (set (mem (plus (reg:SI SP_REGNUM) (const_int -16)))
1021 (set (mem (plus (reg:SI SP_REGNUM) (const_int -12)))
1023 (set (mem (plus (reg:SI SP_REGNUM) (const_int -8)))
1025 (set (mem (plus (reg:SI SP_REGNUM) (const_int -4)))
1027 (set (reg:SI SP_REGNUM)
1028 (plus (reg:SI SP_REGNUM) (const_int -32-imm8u)))]) */
1030 /* Calculate the number of registers that will be pushed.
1031 Since $fp, $gp, and $lp is always pushed with v3push instruction,
1032 we need to count these three registers.
1033 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1034 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1035 num_use_regs
= Re
- Rb
+ 1 + 3;
1037 /* In addition to used registers,
1038 we need one more space for (set sp sp-x-imm8u) rtx. */
1039 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1040 rtvec_alloc (num_use_regs
+ 1));
1043 /* Initialize offset and start to create push behavior. */
1044 offset
= -(num_use_regs
* 4);
1046 /* Create (set mem regX) from Rb, Rb+1 up to Re.
1047 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1048 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1049 for (regno
= Rb
; regno
<= Re
; regno
++)
1051 reg
= gen_rtx_REG (SImode
, regno
);
1052 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1055 push_rtx
= gen_rtx_SET (mem
, reg
);
1056 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1057 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1058 offset
= offset
+ 4;
1062 /* Create (set mem fp). */
1063 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1064 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1067 push_rtx
= gen_rtx_SET (mem
, reg
);
1068 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1069 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1070 offset
= offset
+ 4;
1072 /* Create (set mem gp). */
1073 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1074 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1077 push_rtx
= gen_rtx_SET (mem
, reg
);
1078 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1079 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1080 offset
= offset
+ 4;
1082 /* Create (set mem lp). */
1083 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1084 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1087 push_rtx
= gen_rtx_SET (mem
, reg
);
1088 XVECEXP (parallel_insn
, 0, par_index
) = push_rtx
;
1089 RTX_FRAME_RELATED_P (push_rtx
) = 1;
1090 offset
= offset
+ 4;
1093 /* Create (set sp sp-x-imm8u). */
1095 /* We need to re-calculate the offset value again for adjustment. */
1096 offset
= -(num_use_regs
* 4);
1098 = gen_rtx_SET (stack_pointer_rtx
,
1099 plus_constant (Pmode
,
1102 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1103 RTX_FRAME_RELATED_P (adjust_sp_rtx
) = 1;
1105 parallel_insn
= emit_insn (parallel_insn
);
1107 /* The insn rtx 'parallel_insn' will change frame layout.
1108 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1109 generate CFI (Call Frame Information) stuff. */
1110 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1113 /* Function to create a parallel rtx pattern
1114 which presents stack v3pop behavior.
1115 The overall concept are:
1116 "pop registers from memory",
1117 "adjust stack pointer". */
1119 nds32_emit_stack_v3pop (unsigned Rb
,
1133 rtx dwarf
= NULL_RTX
;
1135 /* We need to provide a customized rtx which contains
1136 necessary information for data analysis,
1137 so we create a parallel rtx like this:
1138 (parallel [(set (reg:SI Rb)
1139 (mem (reg:SI SP_REGNUM)))
1141 (mem (plus (reg:SI SP_REGNUM) (const_int 4))))
1144 (mem (plus (reg:SI SP_REGNUM) (const_int 16))))
1145 (set (reg:SI FP_REGNUM)
1146 (mem (plus (reg:SI SP_REGNUM) (const_int 20))))
1147 (set (reg:SI GP_REGNUM)
1148 (mem (plus (reg:SI SP_REGNUM) (const_int 24))))
1149 (set (reg:SI LP_REGNUM)
1150 (mem (plus (reg:SI SP_REGNUM) (const_int 28))))
1151 (set (reg:SI SP_REGNUM)
1152 (plus (reg:SI SP_REGNUM) (const_int 32+imm8u)))]) */
1154 /* Calculate the number of registers that will be poped.
1155 Since $fp, $gp, and $lp is always poped with v3pop instruction,
1156 we need to count these three registers.
1157 Under v3push, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1158 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1159 num_use_regs
= Re
- Rb
+ 1 + 3;
1161 /* In addition to used registers,
1162 we need one more space for (set sp sp+x+imm8u) rtx. */
1163 parallel_insn
= gen_rtx_PARALLEL (VOIDmode
,
1164 rtvec_alloc (num_use_regs
+ 1));
1167 /* Initialize offset and start to create pop behavior. */
1170 /* Create (set regX mem) from Rb, Rb+1 up to Re.
1171 Under v3pop, Rb is $r6, while Re is $r6, $r8, $r10, or $r14.
1172 So there is no need to worry about Rb=Re=SP_REGNUM case. */
1173 for (regno
= Rb
; regno
<= Re
; regno
++)
1175 reg
= gen_rtx_REG (SImode
, regno
);
1176 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1179 pop_rtx
= gen_rtx_SET (reg
, mem
);
1180 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1181 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1182 offset
= offset
+ 4;
1185 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1188 /* Create (set fp mem). */
1189 reg
= gen_rtx_REG (SImode
, FP_REGNUM
);
1190 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1193 pop_rtx
= gen_rtx_SET (reg
, mem
);
1194 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1195 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1196 offset
= offset
+ 4;
1198 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1200 /* Create (set gp mem). */
1201 reg
= gen_rtx_REG (SImode
, GP_REGNUM
);
1202 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1205 pop_rtx
= gen_rtx_SET (reg
, mem
);
1206 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1207 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1208 offset
= offset
+ 4;
1210 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1212 /* Create (set lp mem ). */
1213 reg
= gen_rtx_REG (SImode
, LP_REGNUM
);
1214 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
1217 pop_rtx
= gen_rtx_SET (reg
, mem
);
1218 XVECEXP (parallel_insn
, 0, par_index
) = pop_rtx
;
1219 RTX_FRAME_RELATED_P (pop_rtx
) = 1;
1220 offset
= offset
+ 4;
1222 dwarf
= alloc_reg_note (REG_CFA_RESTORE
, reg
, dwarf
);
1224 /* Create (set sp sp+x+imm8u). */
1226 /* The offset value is already in place. No need to re-calculate it. */
1228 = gen_rtx_SET (stack_pointer_rtx
,
1229 plus_constant (Pmode
,
1232 XVECEXP (parallel_insn
, 0, par_index
) = adjust_sp_rtx
;
1234 if (frame_pointer_needed
)
1236 /* (expr_list:REG_CFA_DEF_CFA (plus:SI (reg/f:SI $sp)
1238 mean reset frame pointer to $sp and reset to offset 0. */
1239 rtx cfa_adjust_rtx
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
1241 dwarf
= alloc_reg_note (REG_CFA_DEF_CFA
, cfa_adjust_rtx
, dwarf
);
1245 /* Tell gcc we adjust SP in this insn. */
1246 dwarf
= alloc_reg_note (REG_CFA_ADJUST_CFA
,
1247 copy_rtx (adjust_sp_rtx
), dwarf
);
1250 parallel_insn
= emit_insn (parallel_insn
);
1252 /* The insn rtx 'parallel_insn' will change frame layout.
1253 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1254 generate CFI (Call Frame Information) stuff. */
1255 RTX_FRAME_RELATED_P (parallel_insn
) = 1;
1257 /* Add CFI info by manual. */
1258 REG_NOTES (parallel_insn
) = dwarf
;
1261 /* Function that may creates more instructions
1262 for large value on adjusting stack pointer.
1264 In nds32 target, 'addi' can be used for stack pointer
1265 adjustment in prologue/epilogue stage.
1266 However, sometimes there are too many local variables so that
1267 the adjustment value is not able to be fit in the 'addi' instruction.
1268 One solution is to move value into a register
1269 and then use 'add' instruction.
1270 In practice, we use TA_REGNUM ($r15) to accomplish this purpose. */
1272 nds32_emit_adjust_frame (rtx to_reg
, rtx from_reg
, int adjust_value
)
1275 rtx frame_adjust_insn
;
1276 rtx adjust_value_rtx
= GEN_INT (adjust_value
);
1278 if (adjust_value
== 0)
1281 if (!satisfies_constraint_Is15 (adjust_value_rtx
))
1283 /* The value is not able to fit in single addi instruction.
1284 Create more instructions of moving value into a register
1285 and then add stack pointer with it. */
1287 /* $r15 is going to be temporary register to hold the value. */
1288 tmp_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
1290 /* Create one more instruction to move value
1291 into the temporary register. */
1292 emit_move_insn (tmp_reg
, adjust_value_rtx
);
1294 /* Create new 'add' rtx. */
1295 frame_adjust_insn
= gen_addsi3 (to_reg
,
1298 /* Emit rtx into insn list and receive its transformed insn rtx. */
1299 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1301 /* Because (tmp_reg <- full_value) may be split into two
1302 rtl patterns, we can not set its RTX_FRAME_RELATED_P.
1303 We need to construct another (sp <- sp + full_value)
1304 and then insert it into sp_adjust_insn's reg note to
1305 represent a frame related expression.
1306 GCC knows how to refer it and output debug information. */
1311 plus_rtx
= plus_constant (Pmode
, from_reg
, adjust_value
);
1312 set_rtx
= gen_rtx_SET (to_reg
, plus_rtx
);
1313 add_reg_note (frame_adjust_insn
, REG_FRAME_RELATED_EXPR
, set_rtx
);
1317 /* Generate sp adjustment instruction if and only if sp_adjust != 0. */
1318 frame_adjust_insn
= gen_addsi3 (to_reg
,
1321 /* Emit rtx into instructions list and receive INSN rtx form. */
1322 frame_adjust_insn
= emit_insn (frame_adjust_insn
);
1325 /* The insn rtx 'sp_adjust_insn' will change frame layout.
1326 We need to use RTX_FRAME_RELATED_P so that GCC is able to
1327 generate CFI (Call Frame Information) stuff. */
1328 RTX_FRAME_RELATED_P (frame_adjust_insn
) = 1;
1331 /* Return true if MODE/TYPE need double word alignment. */
1333 nds32_needs_double_word_align (machine_mode mode
, const_tree type
)
1337 /* Pick up the alignment according to the mode or type. */
1338 align
= NDS32_MODE_TYPE_ALIGN (mode
, type
);
1340 return (align
> PARM_BOUNDARY
);
1343 /* Return true if FUNC is a naked function. */
1345 nds32_naked_function_p (tree func
)
1349 if (TREE_CODE (func
) != FUNCTION_DECL
)
1352 t
= lookup_attribute ("naked", DECL_ATTRIBUTES (func
));
1354 return (t
!= NULL_TREE
);
1357 /* Function that determine whether a load postincrement is a good thing to use
1358 for a given mode. */
1360 nds32_use_load_post_increment (machine_mode mode
)
1362 return (GET_MODE_SIZE (mode
) <= GET_MODE_SIZE(E_DImode
));
1365 /* Function that check if 'X' is a valid address register.
1366 The variable 'STRICT' is very important to
1367 make decision for register number.
1370 => We are in reload pass or after reload pass.
1371 The register number should be strictly limited in general registers.
1374 => Before reload pass, we are free to use any register number. */
1376 nds32_address_register_rtx_p (rtx x
, bool strict
)
1380 if (GET_CODE (x
) != REG
)
1386 return REGNO_OK_FOR_BASE_P (regno
);
1391 /* Function that check if 'INDEX' is valid to be a index rtx for address.
1393 OUTER_MODE : Machine mode of outer address rtx.
1394 INDEX : Check if this rtx is valid to be a index for address.
1395 STRICT : If it is true, we are in reload pass or after reload pass. */
1397 nds32_legitimate_index_p (machine_mode outer_mode
,
1405 switch (GET_CODE (index
))
1408 regno
= REGNO (index
);
1409 /* If we are in reload pass or after reload pass,
1410 we need to limit it to general register. */
1412 return REGNO_OK_FOR_INDEX_P (regno
);
1417 /* The alignment of the integer value is determined by 'outer_mode'. */
1418 switch (GET_MODE_SIZE (outer_mode
))
1421 /* Further check if the value is legal for the 'outer_mode'. */
1422 if (satisfies_constraint_Is15 (index
))
1427 /* Further check if the value is legal for the 'outer_mode'. */
1428 if (satisfies_constraint_Is16 (index
))
1430 /* If it is not under strictly aligned situation,
1431 we can return true without checking alignment. */
1432 if (!cfun
->machine
->strict_aligned_p
)
1434 /* Make sure address is half word alignment. */
1435 else if (NDS32_HALF_WORD_ALIGN_P (INTVAL (index
)))
1441 /* Further check if the value is legal for the 'outer_mode'. */
1442 if (satisfies_constraint_Is17 (index
))
1444 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1446 if (!satisfies_constraint_Is14 (index
))
1450 /* If it is not under strictly aligned situation,
1451 we can return true without checking alignment. */
1452 if (!cfun
->machine
->strict_aligned_p
)
1454 /* Make sure address is word alignment. */
1455 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1461 if (satisfies_constraint_Is17 (gen_int_mode (INTVAL (index
) + 4,
1464 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
1466 if (!satisfies_constraint_Is14 (index
))
1470 /* If it is not under strictly aligned situation,
1471 we can return true without checking alignment. */
1472 if (!cfun
->machine
->strict_aligned_p
)
1474 /* Make sure address is word alignment.
1475 Currently we do not have 64-bit load/store yet,
1476 so we will use two 32-bit load/store instructions to do
1477 memory access and they are single word alignment. */
1478 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (index
)))
1490 op0
= XEXP (index
, 0);
1491 op1
= XEXP (index
, 1);
1493 if (REG_P (op0
) && CONST_INT_P (op1
))
1496 multiplier
= INTVAL (op1
);
1498 /* We only allow (mult reg const_int_1), (mult reg const_int_2),
1499 (mult reg const_int_4) or (mult reg const_int_8). */
1500 if (multiplier
!= 1 && multiplier
!= 2
1501 && multiplier
!= 4 && multiplier
!= 8)
1504 regno
= REGNO (op0
);
1505 /* Limit it in general registers if we are
1506 in reload pass or after reload pass. */
1508 return REGNO_OK_FOR_INDEX_P (regno
);
1516 op0
= XEXP (index
, 0);
1517 op1
= XEXP (index
, 1);
1519 if (REG_P (op0
) && CONST_INT_P (op1
))
1522 /* op1 is already the sv value for use to do left shift. */
1525 /* We only allow (ashift reg const_int_0)
1526 or (ashift reg const_int_1) or (ashift reg const_int_2) or
1527 (ashift reg const_int_3). */
1528 if (sv
!= 0 && sv
!= 1 && sv
!=2 && sv
!= 3)
1531 regno
= REGNO (op0
);
1532 /* Limit it in general registers if we are
1533 in reload pass or after reload pass. */
1535 return REGNO_OK_FOR_INDEX_P (regno
);
1548 nds32_register_pass (
1549 rtl_opt_pass
*(*make_pass_func
) (gcc::context
*),
1550 enum pass_positioning_ops pass_pos
,
1551 const char *ref_pass_name
)
1553 opt_pass
*new_opt_pass
= make_pass_func (g
);
1555 struct register_pass_info insert_pass
=
1557 new_opt_pass
, /* pass */
1558 ref_pass_name
, /* reference_pass_name */
1559 1, /* ref_pass_instance_number */
1560 pass_pos
/* po_op */
1563 register_pass (&insert_pass
);
1566 /* This function is called from nds32_option_override ().
1567 All new passes should be registered here. */
1569 nds32_register_passes (void)
1571 nds32_register_pass (
1572 make_pass_nds32_relax_opt
,
1573 PASS_POS_INSERT_AFTER
,
1577 /* ------------------------------------------------------------------------ */
1579 /* PART 3: Implement target hook stuff definitions. */
1582 /* Computing the Length of an Insn.
1583 Modifies the length assigned to instruction INSN.
1584 LEN is the initially computed length of the insn. */
1586 nds32_adjust_insn_length (rtx_insn
*insn
, int length
)
1588 int adjust_value
= 0;
1589 switch (recog_memoized (insn
))
1591 case CODE_FOR_call_internal
:
1592 case CODE_FOR_call_value_internal
:
1594 if (NDS32_ALIGN_P ())
1596 rtx_insn
*next_insn
= next_active_insn (insn
);
1597 if (next_insn
&& get_attr_length (next_insn
) != 2)
1600 /* We need insert a nop after a noretun function call
1601 to prevent software breakpoint corrupt the next function. */
1602 if (find_reg_note (insn
, REG_NORETURN
, NULL_RTX
))
1610 return length
+ adjust_value
;
1617 /* Storage Layout. */
1619 /* This function will be called just before expansion into rtl. */
1621 nds32_expand_to_rtl_hook (void)
1623 /* We need to set strictly aligned situation.
1624 After that, the memory address checking in nds32_legitimate_address_p()
1625 will take alignment offset into consideration so that it will not create
1626 unaligned [base + offset] access during the rtl optimization. */
1627 cfun
->machine
->strict_aligned_p
= 1;
1631 /* Register Usage. */
1634 nds32_conditional_register_usage (void)
1638 if (TARGET_HARD_FLOAT
)
1640 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1641 regno
<= NDS32_LAST_FPR_REGNUM
; regno
++)
1643 fixed_regs
[regno
] = 0;
1644 if (regno
< NDS32_FIRST_FPR_REGNUM
+ NDS32_MAX_FPR_REGS_FOR_ARGS
)
1645 call_used_regs
[regno
] = 1;
1646 else if (regno
>= NDS32_FIRST_FPR_REGNUM
+ 22
1647 && regno
< NDS32_FIRST_FPR_REGNUM
+ 48)
1648 call_used_regs
[regno
] = 1;
1650 call_used_regs
[regno
] = 0;
1653 else if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1655 for (regno
= NDS32_FIRST_FPR_REGNUM
;
1656 regno
<= NDS32_LAST_FPR_REGNUM
;
1658 fixed_regs
[regno
] = 0;
1663 /* Register Classes. */
1665 static unsigned char
1666 nds32_class_max_nregs (reg_class_t rclass ATTRIBUTE_UNUSED
,
1669 /* Return the maximum number of consecutive registers
1670 needed to represent "mode" in a register of "rclass". */
1671 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
1675 nds32_register_priority (int hard_regno
)
1677 /* Encourage to use r0-r7 for LRA when optimize for size. */
1682 else if (hard_regno
< 16)
1684 else if (hard_regno
< 28)
1691 if (hard_regno
> 27)
1699 nds32_can_change_mode_class (machine_mode from
,
1703 /* Don't spill double-precision register to two singal-precision
1705 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
1706 && GET_MODE_SIZE (from
) != GET_MODE_SIZE (to
))
1708 return !reg_classes_intersect_p (rclass
, FP_REGS
);
1715 /* Stack Layout and Calling Conventions. */
1717 /* There are three kinds of pointer concepts using in GCC compiler:
1719 frame pointer: A pointer to the first location of local variables.
1720 stack pointer: A pointer to the top of a stack frame.
1721 argument pointer: A pointer to the incoming arguments.
1723 In nds32 target calling convention, we are using 8-byte alignment.
1724 Besides, we would like to have each stack frame of a function includes:
1727 1. previous hard frame pointer
1729 3. callee-saved registers
1730 4. <padding bytes> (we will calculte in nds32_compute_stack_frame()
1732 cfun->machine->callee_saved_area_padding_bytes)
1736 2. spilling location
1737 3. <padding bytes> (it will be calculated by GCC itself)
1738 4. incoming arguments
1739 5. <padding bytes> (it will be calculated by GCC itself)
1742 1. <padding bytes> (it will be calculated by GCC itself)
1743 2. outgoing arguments
1745 We 'wrap' these blocks together with
1746 hard frame pointer ($r28) and stack pointer ($r31).
1747 By applying the basic frame/stack/argument pointers concept,
1748 the layout of a stack frame shoule be like this:
1751 old stack pointer -> ----
1753 | | saved arguments for
1754 | | vararg functions
1756 hard frame pointer -> --
1757 & argument pointer | | \
1758 | | previous hardware frame pointer
1760 | | callee-saved registers
1765 | | and incoming arguments
1772 stack pointer -> ----
1774 $SFP and $AP are used to represent frame pointer and arguments pointer,
1775 which will be both eliminated as hard frame pointer. */
1777 /* -- Eliminating Frame Pointer and Arg Pointer. */
1780 nds32_can_eliminate (const int from_reg
, const int to_reg
)
1782 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1785 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1788 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
1791 if (from_reg
== FRAME_POINTER_REGNUM
&& to_reg
== HARD_FRAME_POINTER_REGNUM
)
1797 /* -- Passing Arguments in Registers. */
1800 nds32_function_arg (cumulative_args_t ca
, machine_mode mode
,
1801 const_tree type
, bool named
)
1804 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1806 /* The last time this hook is called,
1807 it is called with MODE == VOIDmode. */
1808 if (mode
== VOIDmode
)
1811 /* For nameless arguments, we need to take care it individually. */
1814 /* If we are under hard float abi, we have arguments passed on the
1815 stack and all situation can be handled by GCC itself. */
1816 if (TARGET_HARD_FLOAT
)
1819 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1821 /* If we still have enough registers to pass argument, pick up
1822 next available register number. */
1824 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1825 return gen_rtx_REG (mode
, regno
);
1828 /* No register available, return NULL_RTX.
1829 The compiler will use stack to pass argument instead. */
1833 /* The following is to handle named argument.
1834 Note that the strategies of TARGET_HARD_FLOAT and !TARGET_HARD_FLOAT
1836 if (TARGET_HARD_FLOAT
)
1838 /* For TARGET_HARD_FLOAT calling convention, we use GPR and FPR
1839 to pass argument. We have to further check TYPE and MODE so
1840 that we can determine which kind of register we shall use. */
1842 /* Note that we need to pass argument entirely in registers under
1844 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
1845 && NDS32_ARG_ENTIRE_IN_FPR_REG_P (cum
->fpr_offset
, mode
, type
))
1847 /* Pick up the next available FPR register number. */
1849 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
);
1850 return gen_rtx_REG (mode
, regno
);
1852 else if (GET_MODE_CLASS (mode
) != MODE_FLOAT
1853 && NDS32_ARG_ENTIRE_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1855 /* Pick up the next available GPR register number. */
1857 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1858 return gen_rtx_REG (mode
, regno
);
1863 /* For !TARGET_HARD_FLOAT calling convention, we always use GPR to pass
1864 argument. Since we allow to pass argument partially in registers,
1865 we can just return it if there are still registers available. */
1866 if (NDS32_ARG_PARTIAL_IN_GPR_REG_P (cum
->gpr_offset
, mode
, type
))
1868 /* Pick up the next available register number. */
1870 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
);
1871 return gen_rtx_REG (mode
, regno
);
1876 /* No register available, return NULL_RTX.
1877 The compiler will use stack to pass argument instead. */
1882 nds32_must_pass_in_stack (machine_mode mode
, const_tree type
)
1884 /* Return true if a type must be passed in memory.
1885 If it is NOT using hard float abi, small aggregates can be
1886 passed in a register even we are calling a variadic function.
1887 So there is no need to take padding into consideration. */
1888 if (TARGET_HARD_FLOAT
)
1889 return must_pass_in_stack_var_size_or_pad (mode
, type
);
1891 return must_pass_in_stack_var_size (mode
, type
);
1895 nds32_arg_partial_bytes (cumulative_args_t ca
, machine_mode mode
,
1896 tree type
, bool named ATTRIBUTE_UNUSED
)
1898 /* Returns the number of bytes at the beginning of an argument that
1899 must be put in registers. The value must be zero for arguments that are
1900 passed entirely in registers or that are entirely pushed on the stack.
1901 Besides, TARGET_FUNCTION_ARG for these arguments should return the
1902 first register to be used by the caller for this argument. */
1903 unsigned int needed_reg_count
;
1904 unsigned int remaining_reg_count
;
1905 CUMULATIVE_ARGS
*cum
;
1907 cum
= get_cumulative_args (ca
);
1909 /* Under hard float abi, we better have argument entirely passed in
1910 registers or pushed on the stack so that we can reduce the complexity
1911 of dealing with cum->gpr_offset and cum->fpr_offset. */
1912 if (TARGET_HARD_FLOAT
)
1915 /* If we have already runned out of argument registers, return zero
1916 so that the argument will be entirely pushed on the stack. */
1917 if (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1918 >= NDS32_GPR_ARG_FIRST_REGNUM
+ NDS32_MAX_GPR_REGS_FOR_ARGS
)
1921 /* Calculate how many registers do we need for this argument. */
1922 needed_reg_count
= NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1924 /* Calculate how many argument registers have left for passing argument.
1925 Note that we should count it from next available register number. */
1927 = NDS32_MAX_GPR_REGS_FOR_ARGS
1928 - (NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1929 - NDS32_GPR_ARG_FIRST_REGNUM
);
1931 /* Note that we have to return the nubmer of bytes, not registers count. */
1932 if (needed_reg_count
> remaining_reg_count
)
1933 return remaining_reg_count
* UNITS_PER_WORD
;
1939 nds32_function_arg_advance (cumulative_args_t ca
, machine_mode mode
,
1940 const_tree type
, bool named
)
1942 CUMULATIVE_ARGS
*cum
= get_cumulative_args (ca
);
1946 /* We need to further check TYPE and MODE so that we can determine
1947 which kind of register we shall advance. */
1949 /* Under hard float abi, we may advance FPR registers. */
1950 if (TARGET_HARD_FLOAT
&& GET_MODE_CLASS (mode
) == MODE_FLOAT
)
1953 = NDS32_AVAILABLE_REGNUM_FOR_FPR_ARG (cum
->fpr_offset
, mode
, type
)
1954 - NDS32_FPR_ARG_FIRST_REGNUM
1955 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1960 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1961 - NDS32_GPR_ARG_FIRST_REGNUM
1962 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1967 /* If this nameless argument is NOT under TARGET_HARD_FLOAT,
1968 we can advance next register as well so that caller is
1969 able to pass arguments in registers and callee must be
1970 in charge of pushing all of them into stack. */
1971 if (!TARGET_HARD_FLOAT
)
1974 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
1975 - NDS32_GPR_ARG_FIRST_REGNUM
1976 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
1982 nds32_function_arg_boundary (machine_mode mode
, const_tree type
)
1984 return (nds32_needs_double_word_align (mode
, type
)
1985 ? NDS32_DOUBLE_WORD_ALIGNMENT
1989 /* -- How Scalar Function Values Are Returned. */
1992 nds32_function_value (const_tree ret_type
,
1993 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1994 bool outgoing ATTRIBUTE_UNUSED
)
1999 mode
= TYPE_MODE (ret_type
);
2000 unsignedp
= TYPE_UNSIGNED (ret_type
);
2002 if (INTEGRAL_TYPE_P (ret_type
))
2003 mode
= promote_mode (ret_type
, mode
, &unsignedp
);
2005 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2006 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2008 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2012 nds32_libcall_value (machine_mode mode
,
2013 const_rtx fun ATTRIBUTE_UNUSED
)
2015 if (TARGET_HARD_FLOAT
&& (mode
== SFmode
|| mode
== DFmode
))
2016 return gen_rtx_REG (mode
, NDS32_FPR_RET_FIRST_REGNUM
);
2018 return gen_rtx_REG (mode
, NDS32_GPR_RET_FIRST_REGNUM
);
2022 nds32_function_value_regno_p (const unsigned int regno
)
2024 if (regno
== NDS32_GPR_RET_FIRST_REGNUM
2025 || (TARGET_HARD_FLOAT
2026 && regno
== NDS32_FPR_RET_FIRST_REGNUM
))
2032 /* -- How Large Values Are Returned. */
2035 nds32_return_in_memory (const_tree type
,
2036 const_tree fntype ATTRIBUTE_UNUSED
)
2038 /* Note that int_size_in_bytes can return -1 if the size can vary
2039 or is larger than an integer. */
2040 HOST_WIDE_INT size
= int_size_in_bytes (type
);
2042 /* For COMPLEX_TYPE, if the total size cannot be hold within two registers,
2043 the return value is supposed to be in memory. We need to be aware of
2044 that the size may be -1. */
2045 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2046 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2049 /* If it is BLKmode and the total size cannot be hold within two registers,
2050 the return value is supposed to be in memory. We need to be aware of
2051 that the size may be -1. */
2052 if (TYPE_MODE (type
) == BLKmode
)
2053 if (size
< 0 || size
> 2 * UNITS_PER_WORD
)
2056 /* For other cases, having result in memory is unnecessary. */
2060 /* -- Function Entry and Exit. */
2062 /* The content produced from this function
2063 will be placed before prologue body. */
2065 nds32_asm_function_prologue (FILE *file
)
2068 const char *func_name
;
2072 /* All stack frame information is supposed to be
2073 already computed when expanding prologue.
2074 The result is in cfun->machine.
2075 DO NOT call nds32_compute_stack_frame() here
2076 because it may corrupt the essential information. */
2078 fprintf (file
, "\t! BEGIN PROLOGUE\n");
2079 fprintf (file
, "\t! fp needed: %d\n", frame_pointer_needed
);
2080 fprintf (file
, "\t! pretend_args: %d\n", cfun
->machine
->va_args_size
);
2081 fprintf (file
, "\t! local_size: %d\n", cfun
->machine
->local_size
);
2082 fprintf (file
, "\t! out_args_size: %d\n", cfun
->machine
->out_args_size
);
2084 /* Use df_regs_ever_live_p() to detect if the register
2085 is ever used in the current function. */
2086 fprintf (file
, "\t! registers ever_live: ");
2087 for (r
= 0; r
< 65; r
++)
2089 if (df_regs_ever_live_p (r
))
2090 fprintf (file
, "%s, ", reg_names
[r
]);
2094 /* Display the attributes of this function. */
2095 fprintf (file
, "\t! function attributes: ");
2096 /* Get the attributes tree list.
2097 Note that GCC builds attributes list with reverse order. */
2098 attrs
= DECL_ATTRIBUTES (current_function_decl
);
2100 /* If there is no any attribute, print out "None". */
2102 fprintf (file
, "None");
2104 /* If there are some attributes, try if we need to
2105 construct isr vector information. */
2106 func_name
= IDENTIFIER_POINTER (DECL_NAME (current_function_decl
));
2107 nds32_construct_isr_vectors_information (attrs
, func_name
);
2109 /* Display all attributes of this function. */
2112 name
= TREE_PURPOSE (attrs
);
2113 fprintf (file
, "%s ", IDENTIFIER_POINTER (name
));
2115 /* Pick up the next attribute. */
2116 attrs
= TREE_CHAIN (attrs
);
2121 /* After rtl prologue has been expanded, this function is used. */
2123 nds32_asm_function_end_prologue (FILE *file
)
2125 fprintf (file
, "\t! END PROLOGUE\n");
2127 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2128 we can generate special directive: ".omit_fp_begin"
2129 to guide linker doing fp-as-gp optimization.
2130 However, for a naked function, which means
2131 it should not have prologue/epilogue,
2132 using fp-as-gp still requires saving $fp by push/pop behavior and
2133 there is no benefit to use fp-as-gp on such small function.
2134 So we need to make sure this function is NOT naked as well. */
2135 if (!frame_pointer_needed
2136 && !cfun
->machine
->naked_p
2137 && cfun
->machine
->fp_as_gp_p
)
2139 fprintf (file
, "\t! ----------------------------------------\n");
2140 fprintf (file
, "\t! Guide linker to do "
2141 "link time optimization: fp-as-gp\n");
2142 fprintf (file
, "\t! We add one more instruction to "
2143 "initialize $fp near to $gp location.\n");
2144 fprintf (file
, "\t! If linker fails to use fp-as-gp transformation,\n");
2145 fprintf (file
, "\t! this extra instruction should be "
2146 "eliminated at link stage.\n");
2147 fprintf (file
, "\t.omit_fp_begin\n");
2148 fprintf (file
, "\tla\t$fp,_FP_BASE_\n");
2149 fprintf (file
, "\t! ----------------------------------------\n");
2153 /* Before rtl epilogue has been expanded, this function is used. */
2155 nds32_asm_function_begin_epilogue (FILE *file
)
2157 /* If frame pointer is NOT needed and -mfp-as-gp is issued,
2158 we can generate special directive: ".omit_fp_end"
2159 to claim fp-as-gp optimization range.
2160 However, for a naked function,
2161 which means it should not have prologue/epilogue,
2162 using fp-as-gp still requires saving $fp by push/pop behavior and
2163 there is no benefit to use fp-as-gp on such small function.
2164 So we need to make sure this function is NOT naked as well. */
2165 if (!frame_pointer_needed
2166 && !cfun
->machine
->naked_p
2167 && cfun
->machine
->fp_as_gp_p
)
2169 fprintf (file
, "\t! ----------------------------------------\n");
2170 fprintf (file
, "\t! Claim the range of fp-as-gp "
2171 "link time optimization\n");
2172 fprintf (file
, "\t.omit_fp_end\n");
2173 fprintf (file
, "\t! ----------------------------------------\n");
2176 fprintf (file
, "\t! BEGIN EPILOGUE\n");
2179 /* The content produced from this function
2180 will be placed after epilogue body. */
2182 nds32_asm_function_epilogue (FILE *file
)
2184 fprintf (file
, "\t! END EPILOGUE\n");
2188 nds32_asm_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
2189 HOST_WIDE_INT delta
,
2190 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
,
2195 /* Make sure unwind info is emitted for the thunk if needed. */
2196 final_start_function (emit_barrier (), file
, 1);
2198 this_regno
= (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
)
2204 if (satisfies_constraint_Is15 (GEN_INT (delta
)))
2206 fprintf (file
, "\taddi\t$r%d, $r%d, " HOST_WIDE_INT_PRINT_DEC
"\n",
2207 this_regno
, this_regno
, delta
);
2209 else if (satisfies_constraint_Is20 (GEN_INT (delta
)))
2211 fprintf (file
, "\tmovi\t$ta, " HOST_WIDE_INT_PRINT_DEC
"\n", delta
);
2212 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2217 "\tsethi\t$ta, hi20(" HOST_WIDE_INT_PRINT_DEC
")\n",
2220 "\tori\t$ta, $ta, lo12(" HOST_WIDE_INT_PRINT_DEC
")\n",
2222 fprintf (file
, "\tadd\t$r%d, $r%d, $ta\n", this_regno
, this_regno
);
2226 fprintf (file
, "\tb\t");
2227 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
2228 fprintf (file
, "\n");
2230 final_end_function ();
2233 /* -- Permitting tail calls. */
2235 /* Return true if it is ok to do sibling call optimization. */
2237 nds32_function_ok_for_sibcall (tree decl
,
2238 tree exp ATTRIBUTE_UNUSED
)
2240 /* The DECL is NULL if it is an indirect call. */
2242 /* 1. Do not apply sibling call if -mv3push is enabled,
2243 because pop25 instruction also represents return behavior.
2244 2. If this function is a variadic function, do not apply sibling call
2245 because the stack layout may be a mess.
2246 3. We don't want to apply sibling call optimization for indirect
2247 sibcall because the pop behavior in epilogue may pollute the
2248 content of caller-saved regsiter when the register is used for
2249 indirect sibcall. */
2250 return (!TARGET_V3PUSH
2251 && (cfun
->machine
->va_args_size
== 0)
2255 /* Determine whether we need to enable warning for function return check. */
2257 nds32_warn_func_return (tree decl
)
2259 /* Naked functions are implemented entirely in assembly, including the
2260 return sequence, so suppress warnings about this. */
2261 return !nds32_naked_function_p (decl
);
2265 /* Implementing the Varargs Macros. */
2268 nds32_setup_incoming_varargs (cumulative_args_t ca
,
2271 int *pretend_args_size
,
2272 int second_time ATTRIBUTE_UNUSED
)
2274 unsigned int total_args_regs
;
2275 unsigned int num_of_used_regs
;
2276 unsigned int remaining_reg_count
;
2277 CUMULATIVE_ARGS
*cum
;
2279 /* If we are under hard float abi, we do not need to set *pretend_args_size.
2280 So that all nameless arguments are pushed by caller and all situation
2281 can be handled by GCC itself. */
2282 if (TARGET_HARD_FLOAT
)
2285 /* We are using NDS32_MAX_GPR_REGS_FOR_ARGS registers,
2286 counting from NDS32_GPR_ARG_FIRST_REGNUM, for saving incoming arguments.
2287 However, for nameless(anonymous) arguments, we should push them on the
2288 stack so that all the nameless arguments appear to have been passed
2289 consecutively in the memory for accessing. Hence, we need to check and
2290 exclude the registers that are used for named arguments. */
2292 cum
= get_cumulative_args (ca
);
2294 /* The MODE and TYPE describe the last argument.
2295 We need those information to determine the remaining registers
2298 = NDS32_MAX_GPR_REGS_FOR_ARGS
+ NDS32_GPR_ARG_FIRST_REGNUM
;
2300 = NDS32_AVAILABLE_REGNUM_FOR_GPR_ARG (cum
->gpr_offset
, mode
, type
)
2301 + NDS32_NEED_N_REGS_FOR_ARG (mode
, type
);
2303 remaining_reg_count
= total_args_regs
- num_of_used_regs
;
2304 *pretend_args_size
= remaining_reg_count
* UNITS_PER_WORD
;
2310 nds32_strict_argument_naming (cumulative_args_t ca ATTRIBUTE_UNUSED
)
2312 /* If this hook returns true, the named argument of FUNCTION_ARG is always
2313 true for named arguments, and false for unnamed arguments. */
2318 /* Trampolines for Nested Functions. */
2321 nds32_asm_trampoline_template (FILE *f
)
2323 if (TARGET_REDUCED_REGS
)
2325 /* Trampoline is not supported on reduced-set registers yet. */
2326 sorry ("a nested function is not supported for reduced registers");
2330 asm_fprintf (f
, "\t! Trampoline code template\n");
2331 asm_fprintf (f
, "\t! This code fragment will be copied "
2332 "into stack on demand\n");
2334 asm_fprintf (f
, "\tmfusr\t$r16,$pc\n");
2335 asm_fprintf (f
, "\tlwi\t$r15,[$r16 + 20] "
2336 "! load nested function address\n");
2337 asm_fprintf (f
, "\tlwi\t$r16,[$r16 + 16] "
2338 "! load chain_value\n");
2339 asm_fprintf (f
, "\tjr\t$r15\n");
2342 /* Preserve space ($pc + 16) for saving chain_value,
2343 nds32_trampoline_init will fill the value in this slot. */
2344 asm_fprintf (f
, "\t! space for saving chain_value\n");
2345 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2347 /* Preserve space ($pc + 20) for saving nested function address,
2348 nds32_trampoline_init will fill the value in this slot. */
2349 asm_fprintf (f
, "\t! space for saving nested function address\n");
2350 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
2353 /* Emit RTL insns to initialize the variable parts of a trampoline. */
2355 nds32_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain_value
)
2359 /* Nested function address. */
2361 /* The memory rtx that is going to
2362 be filled with chain_value. */
2363 rtx chain_value_mem
;
2364 /* The memory rtx that is going to
2365 be filled with nested function address. */
2366 rtx nested_func_mem
;
2368 /* Start address of trampoline code in stack, for doing cache sync. */
2369 rtx sync_cache_addr
;
2370 /* Temporary register for sync instruction. */
2372 /* Instruction-cache sync instruction,
2373 requesting an argument as starting address. */
2375 /* For convenience reason of doing comparison. */
2376 int tramp_align_in_bytes
;
2378 /* Trampoline is not supported on reduced-set registers yet. */
2379 if (TARGET_REDUCED_REGS
)
2380 sorry ("a nested function is not supported for reduced registers");
2382 /* STEP 1: Copy trampoline code template into stack,
2383 fill up essential data into stack. */
2385 /* Extract nested function address rtx. */
2386 fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
2388 /* m_tramp is memory rtx that is going to be filled with trampoline code.
2389 We have nds32_asm_trampoline_template() to emit template pattern. */
2390 emit_block_move (m_tramp
, assemble_trampoline_template (),
2391 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
2393 /* After copying trampoline code into stack,
2394 fill chain_value into stack. */
2395 chain_value_mem
= adjust_address (m_tramp
, SImode
, 16);
2396 emit_move_insn (chain_value_mem
, chain_value
);
2397 /* After copying trampoline code int stack,
2398 fill nested function address into stack. */
2399 nested_func_mem
= adjust_address (m_tramp
, SImode
, 20);
2400 emit_move_insn (nested_func_mem
, fnaddr
);
2402 /* STEP 2: Sync instruction-cache. */
2404 /* We have successfully filled trampoline code into stack.
2405 However, in order to execute code in stack correctly,
2406 we must sync instruction cache. */
2407 sync_cache_addr
= XEXP (m_tramp
, 0);
2408 tmp_reg
= gen_reg_rtx (SImode
);
2409 isync_insn
= gen_unspec_volatile_isync (tmp_reg
);
2411 /* Because nds32_cache_block_size is in bytes,
2412 we get trampoline alignment in bytes for convenient comparison. */
2413 tramp_align_in_bytes
= TRAMPOLINE_ALIGNMENT
/ BITS_PER_UNIT
;
2415 if (tramp_align_in_bytes
>= nds32_cache_block_size
2416 && (tramp_align_in_bytes
% nds32_cache_block_size
) == 0)
2418 /* Under this condition, the starting address of trampoline
2419 must be aligned to the starting address of each cache block
2420 and we do not have to worry about cross-boundary issue. */
2422 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2423 / nds32_cache_block_size
;
2426 emit_move_insn (tmp_reg
,
2427 plus_constant (Pmode
, sync_cache_addr
,
2428 nds32_cache_block_size
* i
));
2429 emit_insn (isync_insn
);
2432 else if (TRAMPOLINE_SIZE
> nds32_cache_block_size
)
2434 /* The starting address of trampoline code
2435 may not be aligned to the cache block,
2436 so the trampoline code may be across two cache block.
2437 We need to sync the last element, which is 4-byte size,
2438 of trampoline template. */
2440 i
< (TRAMPOLINE_SIZE
+ nds32_cache_block_size
- 1)
2441 / nds32_cache_block_size
;
2444 emit_move_insn (tmp_reg
,
2445 plus_constant (Pmode
, sync_cache_addr
,
2446 nds32_cache_block_size
* i
));
2447 emit_insn (isync_insn
);
2450 /* The last element of trampoline template is 4-byte size. */
2451 emit_move_insn (tmp_reg
,
2452 plus_constant (Pmode
, sync_cache_addr
,
2453 TRAMPOLINE_SIZE
- 4));
2454 emit_insn (isync_insn
);
2458 /* This is the simplest case.
2459 Because TRAMPOLINE_SIZE is less than or
2460 equal to nds32_cache_block_size,
2461 we can just sync start address and
2462 the last element of trampoline code. */
2464 /* Sync starting address of tampoline code. */
2465 emit_move_insn (tmp_reg
, sync_cache_addr
);
2466 emit_insn (isync_insn
);
2467 /* Sync the last element, which is 4-byte size,
2468 of trampoline template. */
2469 emit_move_insn (tmp_reg
,
2470 plus_constant (Pmode
, sync_cache_addr
,
2471 TRAMPOLINE_SIZE
- 4));
2472 emit_insn (isync_insn
);
2475 /* Set instruction serialization barrier
2476 to guarantee the correct operations. */
2477 emit_insn (gen_unspec_volatile_isb ());
2481 /* Addressing Modes. */
2484 nds32_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
2486 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
2488 /* When using floating-point instructions,
2489 we don't allow 'addr' to be [symbol_ref], [CONST] pattern. */
2490 if ((mode
== DFmode
|| mode
== SFmode
)
2491 && (GET_CODE (x
) == SYMBOL_REF
2492 || GET_CODE(x
) == CONST
))
2495 /* Allow [post_modify] addressing mode, when using FPU instructions. */
2496 if (GET_CODE (x
) == POST_MODIFY
2499 if (GET_CODE (XEXP (x
, 0)) == REG
2500 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2502 rtx plus_op
= XEXP (x
, 1);
2503 rtx op0
= XEXP (plus_op
, 0);
2504 rtx op1
= XEXP (plus_op
, 1);
2506 if (nds32_address_register_rtx_p (op0
, strict
)
2507 && CONST_INT_P (op1
))
2509 if (satisfies_constraint_Is14 (op1
))
2511 /* If it is not under strictly aligned situation,
2512 we can return true without checking alignment. */
2513 if (!cfun
->machine
->strict_aligned_p
)
2515 /* Make sure address is word alignment.
2516 Currently we do not have 64-bit load/store yet,
2517 so we will use two 32-bit load/store instructions to do
2518 memory access and they are single word alignment. */
2519 else if (NDS32_SINGLE_WORD_ALIGN_P (INTVAL (op1
)))
2527 /* For (mem:DI addr) or (mem:DF addr) case,
2528 we only allow 'addr' to be [reg], [symbol_ref],
2529 [const], or [reg + const_int] pattern. */
2530 if (mode
== DImode
|| mode
== DFmode
)
2532 /* Allow [Reg + const_int] addressing mode. */
2533 if (GET_CODE (x
) == PLUS
)
2535 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2536 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
)
2537 && CONST_INT_P (XEXP (x
, 1)))
2539 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2540 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
)
2541 && CONST_INT_P (XEXP (x
, 0)))
2545 /* Allow [post_inc] and [post_dec] addressing mode. */
2546 if (GET_CODE (x
) == POST_INC
|| GET_CODE (x
) == POST_DEC
)
2548 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2552 /* Now check [reg], [symbol_ref], and [const]. */
2553 if (GET_CODE (x
) != REG
2554 && GET_CODE (x
) != SYMBOL_REF
2555 && GET_CODE (x
) != CONST
)
2559 /* Check if 'x' is a valid address. */
2560 switch (GET_CODE (x
))
2563 /* (mem (reg A)) => [Ra] */
2564 return nds32_address_register_rtx_p (x
, strict
);
2567 /* (mem (symbol_ref A)) => [symbol_ref] */
2568 /* If -mcmodel=large, the 'symbol_ref' is not a valid address
2569 during or after LRA/reload phase. */
2570 if (TARGET_CMODEL_LARGE
2571 && (reload_completed
2572 || reload_in_progress
2573 || lra_in_progress
))
2575 /* If -mcmodel=medium and the symbol references to rodata section,
2576 the 'symbol_ref' is not a valid address during or after
2577 LRA/reload phase. */
2578 if (TARGET_CMODEL_MEDIUM
2579 && NDS32_SYMBOL_REF_RODATA_P (x
)
2580 && (reload_completed
2581 || reload_in_progress
2582 || lra_in_progress
))
2588 /* (mem (const (...)))
2589 => [ + const_addr ], where const_addr = symbol_ref + const_int */
2590 if (GET_CODE (XEXP (x
, 0)) == PLUS
)
2592 rtx plus_op
= XEXP (x
, 0);
2594 rtx op0
= XEXP (plus_op
, 0);
2595 rtx op1
= XEXP (plus_op
, 1);
2597 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2599 /* Now we see the [ + const_addr ] pattern, but we need
2600 some further checking. */
2601 /* If -mcmodel=large, the 'const_addr' is not a valid address
2602 during or after LRA/reload phase. */
2603 if (TARGET_CMODEL_LARGE
2604 && (reload_completed
2605 || reload_in_progress
2606 || lra_in_progress
))
2608 /* If -mcmodel=medium and the symbol references to rodata section,
2609 the 'const_addr' is not a valid address during or after
2610 LRA/reload phase. */
2611 if (TARGET_CMODEL_MEDIUM
2612 && NDS32_SYMBOL_REF_RODATA_P (op0
)
2613 && (reload_completed
2614 || reload_in_progress
2615 || lra_in_progress
))
2618 /* At this point we can make sure 'const_addr' is a
2627 /* (mem (post_modify (reg) (plus (reg) (reg))))
2629 /* (mem (post_modify (reg) (plus (reg) (const_int))))
2630 => [Ra], const_int */
2631 if (GET_CODE (XEXP (x
, 0)) == REG
2632 && GET_CODE (XEXP (x
, 1)) == PLUS
)
2634 rtx plus_op
= XEXP (x
, 1);
2636 rtx op0
= XEXP (plus_op
, 0);
2637 rtx op1
= XEXP (plus_op
, 1);
2639 if (nds32_address_register_rtx_p (op0
, strict
)
2640 && nds32_legitimate_index_p (mode
, op1
, strict
))
2650 /* (mem (post_inc reg)) => [Ra], 1/2/4 */
2651 /* (mem (post_dec reg)) => [Ra], -1/-2/-4 */
2652 /* The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
2653 We only need to deal with register Ra. */
2654 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
))
2660 /* (mem (plus reg const_int))
2662 /* (mem (plus reg reg))
2664 /* (mem (plus (mult reg const_int) reg))
2665 => [Ra + Rb << sv] */
2666 if (nds32_address_register_rtx_p (XEXP (x
, 0), strict
)
2667 && nds32_legitimate_index_p (mode
, XEXP (x
, 1), strict
))
2669 else if (nds32_address_register_rtx_p (XEXP (x
, 1), strict
)
2670 && nds32_legitimate_index_p (mode
, XEXP (x
, 0), strict
))
2676 /* (mem (lo_sum (reg) (symbol_ref))) */
2677 /* (mem (lo_sum (reg) (const))) */
2678 gcc_assert (REG_P (XEXP (x
, 0)));
2679 if (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
2680 || GET_CODE (XEXP (x
, 1)) == CONST
)
2681 return nds32_legitimate_address_p (mode
, XEXP (x
, 1), strict
);
2691 /* Condition Code Status. */
2693 /* -- Representation of condition codes using registers. */
2696 nds32_canonicalize_comparison (int *code
,
2697 rtx
*op0 ATTRIBUTE_UNUSED
,
2699 bool op0_preserve_value ATTRIBUTE_UNUSED
)
2701 /* When the instruction combination pass tries to combine a comparison insn
2702 with its previous insns, it also transforms the operator in order to
2703 minimize its constant field. For example, it tries to transform a
2704 comparison insn from
2707 (const_int 10 [0xa])))
2711 (const_int 9 [0x9])))
2713 However, the nds32 target only provides instructions supporting the LTU
2714 operation directly, and the implementation of the pattern "cbranchsi4"
2715 only expands the LTU form. In order to handle the non-LTU operations
2716 generated from passes other than the RTL expansion pass, we have to
2717 implement this hook to revert those changes. Since we only expand the LTU
2718 operator in the RTL expansion pass, we might only need to handle the LEU
2719 case, unless we find other optimization passes perform more aggressive
2722 if (*code
== LEU
&& CONST_INT_P (*op1
))
2724 *op1
= gen_int_mode (INTVAL (*op1
) + 1, SImode
);
2730 /* Describing Relative Costs of Operations. */
2733 nds32_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2737 if ((from
== FP_REGS
&& to
!= FP_REGS
)
2738 || (from
!= FP_REGS
&& to
== FP_REGS
))
2740 else if (from
== HIGH_REGS
|| to
== HIGH_REGS
)
2741 return optimize_size
? 6 : 2;
2747 nds32_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
2748 reg_class_t rclass ATTRIBUTE_UNUSED
,
2749 bool in ATTRIBUTE_UNUSED
)
2754 /* This target hook describes the relative costs of RTL expressions.
2755 Return 'true' when all subexpressions of x have been processed.
2756 Return 'false' to sum the costs of sub-rtx, plus cost of this operation.
2757 Refer to gcc/rtlanal.c for more information. */
2759 nds32_rtx_costs (rtx x
,
2766 return nds32_rtx_costs_impl (x
, mode
, outer_code
, opno
, total
, speed
);
2770 nds32_address_cost (rtx address
,
2775 return nds32_address_cost_impl (address
, mode
, as
, speed
);
2779 /* Dividing the Output into Sections (Texts, Data, . . . ). */
2781 /* If references to a symbol or a constant must be treated differently
2782 depending on something about the variable or function named by the symbol
2783 (such as what section it is in), we use this hook to store flags
2784 in symbol_ref rtx. */
2786 nds32_encode_section_info (tree decl
, rtx rtl
, int new_decl_p
)
2788 default_encode_section_info (decl
, rtl
, new_decl_p
);
2790 /* For the memory rtx, if it references to rodata section, we can store
2791 NDS32_SYMBOL_FLAG_RODATA flag into symbol_ref rtx so that the
2792 nds32_legitimate_address_p() can determine how to treat such symbol_ref
2793 based on -mcmodel=X and this information. */
2794 if (MEM_P (rtl
) && MEM_READONLY_P (rtl
))
2796 rtx addr
= XEXP (rtl
, 0);
2798 if (GET_CODE (addr
) == SYMBOL_REF
)
2800 /* For (mem (symbol_ref X)) case. */
2801 SYMBOL_REF_FLAGS (addr
) |= NDS32_SYMBOL_FLAG_RODATA
;
2803 else if (GET_CODE (addr
) == CONST
2804 && GET_CODE (XEXP (addr
, 0)) == PLUS
)
2806 /* For (mem (const (plus (symbol_ref X) (const_int N)))) case. */
2807 rtx plus_op
= XEXP (addr
, 0);
2808 rtx op0
= XEXP (plus_op
, 0);
2809 rtx op1
= XEXP (plus_op
, 1);
2811 if (GET_CODE (op0
) == SYMBOL_REF
&& CONST_INT_P (op1
))
2812 SYMBOL_REF_FLAGS (op0
) |= NDS32_SYMBOL_FLAG_RODATA
;
2818 /* Defining the Output Assembler Language. */
2820 /* -- The Overall Framework of an Assembler File. */
2823 nds32_asm_file_start (void)
2825 default_file_start ();
2827 /* Tell assembler which ABI we are using. */
2828 fprintf (asm_out_file
, "\t! ABI version\n");
2829 if (TARGET_HARD_FLOAT
)
2830 fprintf (asm_out_file
, "\t.abi_2fp_plus\n");
2832 fprintf (asm_out_file
, "\t.abi_2\n");
2834 /* Tell assembler that this asm code is generated by compiler. */
2835 fprintf (asm_out_file
, "\t! This asm file is generated by compiler\n");
2836 fprintf (asm_out_file
, "\t.flag\tverbatim\n");
2837 /* Give assembler the size of each vector for interrupt handler. */
2838 fprintf (asm_out_file
, "\t! This vector size directive is required "
2839 "for checking inconsistency on interrupt handler\n");
2840 fprintf (asm_out_file
, "\t.vec_size\t%d\n", nds32_isr_vector_size
);
2842 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2845 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V2");
2847 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3");
2849 fprintf (asm_out_file
, "\t! ISA family\t\t: %s\n", "V3M");
2851 if (TARGET_CMODEL_SMALL
)
2852 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "SMALL");
2853 if (TARGET_CMODEL_MEDIUM
)
2854 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "MEDIUM");
2855 if (TARGET_CMODEL_LARGE
)
2856 fprintf (asm_out_file
, "\t! Code model\t\t: %s\n", "LARGE");
2858 fprintf (asm_out_file
, "\t! Endian setting\t: %s\n",
2859 ((TARGET_BIG_ENDIAN
) ? "big-endian"
2860 : "little-endian"));
2861 fprintf (asm_out_file
, "\t! Use SP floating-point instruction\t: %s\n",
2862 ((TARGET_FPU_SINGLE
) ? "Yes"
2864 fprintf (asm_out_file
, "\t! Use DP floating-point instruction\t: %s\n",
2865 ((TARGET_FPU_DOUBLE
) ? "Yes"
2867 fprintf (asm_out_file
, "\t! ABI version\t\t: %s\n",
2868 ((TARGET_HARD_FLOAT
) ? "ABI2FP+"
2871 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2873 fprintf (asm_out_file
, "\t! Use conditional move\t\t: %s\n",
2874 ((TARGET_CMOV
) ? "Yes"
2876 fprintf (asm_out_file
, "\t! Use performance extension\t: %s\n",
2877 ((TARGET_EXT_PERF
) ? "Yes"
2879 fprintf (asm_out_file
, "\t! Use performance extension 2\t: %s\n",
2880 ((TARGET_EXT_PERF2
) ? "Yes"
2882 fprintf (asm_out_file
, "\t! Use string extension\t\t: %s\n",
2883 ((TARGET_EXT_STRING
) ? "Yes"
2886 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2888 fprintf (asm_out_file
, "\t! V3PUSH instructions\t: %s\n",
2889 ((TARGET_V3PUSH
) ? "Yes"
2891 fprintf (asm_out_file
, "\t! 16-bit instructions\t: %s\n",
2892 ((TARGET_16_BIT
) ? "Yes"
2894 fprintf (asm_out_file
, "\t! Reduced registers set\t: %s\n",
2895 ((TARGET_REDUCED_REGS
) ? "Yes"
2898 fprintf (asm_out_file
, "\t! Support unaligned access\t\t: %s\n",
2899 (flag_unaligned_access
? "Yes"
2902 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2905 fprintf (asm_out_file
, "\t! Optimization level\t: -Os\n");
2906 else if (optimize_fast
)
2907 fprintf (asm_out_file
, "\t! Optimization level\t: -Ofast\n");
2908 else if (optimize_debug
)
2909 fprintf (asm_out_file
, "\t! Optimization level\t: -Og\n");
2911 fprintf (asm_out_file
, "\t! Optimization level\t: -O%d\n", optimize
);
2913 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2915 fprintf (asm_out_file
, "\t! Cache block size\t: %d\n",
2916 nds32_cache_block_size
);
2918 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2920 nds32_asm_file_start_for_isr ();
2924 nds32_asm_file_end (void)
2926 nds32_asm_file_end_for_isr ();
2928 fprintf (asm_out_file
, "\t! ------------------------------------\n");
2931 /* -- Output and Generation of Labels. */
2934 nds32_asm_globalize_label (FILE *stream
, const char *name
)
2936 fputs ("\t.global\t", stream
);
2937 assemble_name (stream
, name
);
2938 fputs ("\n", stream
);
2941 /* -- Output of Assembler Instructions. */
2944 nds32_print_operand (FILE *stream
, rtx x
, int code
)
2946 HOST_WIDE_INT one_position
;
2947 HOST_WIDE_INT zero_position
;
2948 bool pick_lsb_p
= false;
2949 bool pick_msb_p
= false;
2957 /* Do nothing special. */
2961 /* Use exact_log2() to search the 0-bit position. */
2962 gcc_assert (CONST_INT_P (x
));
2963 zero_position
= exact_log2 (~UINTVAL (x
) & GET_MODE_MASK (SImode
));
2964 gcc_assert (zero_position
!= -1);
2965 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, zero_position
);
2967 /* No need to handle following process, so return immediately. */
2971 gcc_assert (MEM_P (x
)
2972 && GET_CODE (XEXP (x
, 0)) == PLUS
2973 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
);
2974 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (XEXP (XEXP (x
, 0), 1)));
2976 /* No need to handle following process, so return immediately. */
2979 /* Use exact_log2() to search the 1-bit position. */
2980 gcc_assert (CONST_INT_P (x
));
2981 one_position
= exact_log2 (UINTVAL (x
) & GET_MODE_MASK (SImode
));
2982 gcc_assert (one_position
!= -1);
2983 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, one_position
);
2985 /* No need to handle following process, so return immediately. */
2989 /* X is supposed to be REG rtx. */
2990 gcc_assert (REG_P (x
));
2991 /* Claim that we are going to pick LSB part of X. */
2996 /* X is supposed to be REG rtx. */
2997 gcc_assert (REG_P (x
));
2998 /* Claim that we are going to pick MSB part of X. */
3003 /* 'x' is supposed to be CONST_INT, get the value. */
3004 gcc_assert (CONST_INT_P (x
));
3005 op_value
= INTVAL (x
);
3007 /* According to the Andes architecture,
3008 the system/user register index range is 0 ~ 1023.
3009 In order to avoid conflict between user-specified-integer value
3010 and enum-specified-register value,
3011 the 'enum nds32_intrinsic_registers' value
3012 in nds32_intrinsic.h starts from 1024. */
3013 if (op_value
< 1024 && op_value
>= 0)
3015 /* If user gives integer value directly (0~1023),
3016 we just print out the value. */
3017 fprintf (stream
, HOST_WIDE_INT_PRINT_DEC
, op_value
);
3019 else if (op_value
< 0
3020 || op_value
>= ((int) ARRAY_SIZE (nds32_intrinsic_register_names
)
3023 /* The enum index value for array size is out of range. */
3024 error ("intrinsic register index is out of range");
3028 /* If user applies normal way with __NDS32_REG_XXX__ enum data,
3029 we can print out register name. Remember to substract 1024. */
3030 fprintf (stream
, "%s",
3031 nds32_intrinsic_register_names
[op_value
- 1024]);
3034 /* No need to handle following process, so return immediately. */
3037 case 'R': /* cctl valck */
3038 /* Note the cctl divide to 5 group and share the same name table. */
3039 if (op_value
< 0 || op_value
> 4)
3040 error ("CCTL intrinsic function subtype out of range!");
3041 fprintf (stream
, "%s", nds32_cctl_names
[op_value
]);
3044 case 'T': /* cctl idxwbinv */
3045 /* Note the cctl divide to 5 group and share the same name table. */
3046 if (op_value
< 0 || op_value
> 4)
3047 error ("CCTL intrinsic function subtype out of range!");
3048 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 4]);
3051 case 'U': /* cctl vawbinv */
3052 /* Note the cctl divide to 5 group and share the same name table. */
3053 if (op_value
< 0 || op_value
> 4)
3054 error ("CCTL intrinsic function subtype out of range!");
3055 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 8]);
3058 case 'X': /* cctl idxread */
3059 /* Note the cctl divide to 5 group and share the same name table. */
3060 if (op_value
< 0 || op_value
> 4)
3061 error ("CCTL intrinsic function subtype out of range!");
3062 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 12]);
3065 case 'W': /* cctl idxwitre */
3066 /* Note the cctl divide to 5 group and share the same name table. */
3067 if (op_value
< 0 || op_value
> 4)
3068 error ("CCTL intrinsic function subtype out of range!");
3069 fprintf (stream
, "%s", nds32_cctl_names
[op_value
+ 16]);
3072 case 'Z': /* dpref */
3073 fprintf (stream
, "%s", nds32_dpref_names
[op_value
]);
3078 output_operand_lossage ("invalid operand output code");
3082 switch (GET_CODE (x
))
3086 output_addr_const (stream
, x
);
3090 /* Print a Double-precision register name. */
3091 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3092 && NDS32_IS_FPR_REGNUM (REGNO (x
)))
3095 if (!NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
))
3097 output_operand_lossage ("invalid operand for code '%c'", code
);
3100 fprintf (stream
, "$fd%d", (regno
- NDS32_FIRST_FPR_REGNUM
) >> 1);
3104 /* Print LSB or MSB part of register pair if the
3105 constraint modifier 'L' or 'H' is specified. */
3106 if ((GET_MODE (x
) == DImode
|| GET_MODE (x
) == DFmode
)
3107 && NDS32_IS_GPR_REGNUM (REGNO (x
)))
3109 if ((pick_lsb_p
&& WORDS_BIG_ENDIAN
)
3110 || (pick_msb_p
&& !WORDS_BIG_ENDIAN
))
3112 /* If we would like to print out LSB register under big-endian,
3113 or print out MSB register under little-endian, we need to
3114 increase register number. */
3117 fputs (reg_names
[regno
], stream
);
3122 /* Forbid using static chain register ($r16)
3123 on reduced-set registers configuration. */
3124 if (TARGET_REDUCED_REGS
3125 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3126 sorry ("a nested function is not supported for reduced registers");
3128 /* Normal cases, print out register name. */
3129 fputs (reg_names
[REGNO (x
)], stream
);
3133 output_address (GET_MODE (x
), XEXP (x
, 0));
3137 if (GET_CODE (XEXP (x
, 0)) == CONST_DOUBLE
)
3139 const REAL_VALUE_TYPE
*rv
;
3141 gcc_assert (GET_MODE (x
) == SFmode
);
3143 rv
= CONST_DOUBLE_REAL_VALUE (XEXP (x
, 0));
3144 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3146 fprintf (stream
, "hi20(0x%lx)", val
);
3153 const REAL_VALUE_TYPE
*rv
;
3155 gcc_assert (GET_MODE (x
) == SFmode
);
3157 rv
= CONST_DOUBLE_REAL_VALUE (x
);
3158 REAL_VALUE_TO_TARGET_SINGLE (*rv
, val
);
3160 fprintf (stream
, "0x%lx", val
);
3166 output_addr_const (stream
, x
);
3170 /* Generally, output_addr_const () is able to handle most cases.
3171 We want to see what CODE could appear,
3172 so we use gcc_unreachable() to stop it. */
3180 nds32_print_operand_address (FILE *stream
, machine_mode
/*mode*/, rtx x
)
3184 switch (GET_CODE (x
))
3188 /* [ + symbol_ref] */
3189 /* [ + const_addr], where const_addr = symbol_ref + const_int */
3190 fputs ("[ + ", stream
);
3191 output_addr_const (stream
, x
);
3192 fputs ("]", stream
);
3196 /* Forbid using static chain register ($r16)
3197 on reduced-set registers configuration. */
3198 if (TARGET_REDUCED_REGS
3199 && REGNO (x
) == STATIC_CHAIN_REGNUM
)
3200 sorry ("a nested function is not supported for reduced registers");
3203 fprintf (stream
, "[%s]", reg_names
[REGNO (x
)]);
3210 /* Checking op0, forbid using static chain register ($r16)
3211 on reduced-set registers configuration. */
3212 if (TARGET_REDUCED_REGS
3214 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3215 sorry ("a nested function is not supported for reduced registers");
3216 /* Checking op1, forbid using static chain register ($r16)
3217 on reduced-set registers configuration. */
3218 if (TARGET_REDUCED_REGS
3220 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3221 sorry ("a nested function is not supported for reduced registers");
3223 if (REG_P (op0
) && CONST_INT_P (op1
))
3226 fprintf (stream
, "[%s + (" HOST_WIDE_INT_PRINT_DEC
")]",
3227 reg_names
[REGNO (op0
)], INTVAL (op1
));
3229 else if (REG_P (op0
) && REG_P (op1
))
3232 fprintf (stream
, "[%s + %s]",
3233 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3235 else if (GET_CODE (op0
) == MULT
&& REG_P (op1
))
3238 From observation, the pattern looks like:
3239 (plus:SI (mult:SI (reg:SI 58)
3240 (const_int 4 [0x4]))
3244 /* We need to set sv to output shift value. */
3245 if (INTVAL (XEXP (op0
, 1)) == 1)
3247 else if (INTVAL (XEXP (op0
, 1)) == 2)
3249 else if (INTVAL (XEXP (op0
, 1)) == 4)
3251 else if (INTVAL (XEXP (op0
, 1)) == 8)
3256 fprintf (stream
, "[%s + %s << %d]",
3257 reg_names
[REGNO (op1
)],
3258 reg_names
[REGNO (XEXP (op0
, 0))],
3263 /* The control flow is not supposed to be here. */
3271 /* (post_modify (regA) (plus (regA) (regB)))
3272 (post_modify (regA) (plus (regA) (const_int)))
3273 We would like to extract
3274 regA and regB (or const_int) from plus rtx. */
3275 op0
= XEXP (XEXP (x
, 1), 0);
3276 op1
= XEXP (XEXP (x
, 1), 1);
3278 /* Checking op0, forbid using static chain register ($r16)
3279 on reduced-set registers configuration. */
3280 if (TARGET_REDUCED_REGS
3282 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3283 sorry ("a nested function is not supported for reduced registers");
3284 /* Checking op1, forbid using static chain register ($r16)
3285 on reduced-set registers configuration. */
3286 if (TARGET_REDUCED_REGS
3288 && REGNO (op1
) == STATIC_CHAIN_REGNUM
)
3289 sorry ("a nested function is not supported for reduced registers");
3291 if (REG_P (op0
) && REG_P (op1
))
3294 fprintf (stream
, "[%s], %s",
3295 reg_names
[REGNO (op0
)], reg_names
[REGNO (op1
)]);
3297 else if (REG_P (op0
) && CONST_INT_P (op1
))
3300 fprintf (stream
, "[%s], " HOST_WIDE_INT_PRINT_DEC
,
3301 reg_names
[REGNO (op0
)], INTVAL (op1
));
3305 /* The control flow is not supposed to be here. */
3316 /* Checking op0, forbid using static chain register ($r16)
3317 on reduced-set registers configuration. */
3318 if (TARGET_REDUCED_REGS
3320 && REGNO (op0
) == STATIC_CHAIN_REGNUM
)
3321 sorry ("a nested function is not supported for reduced registers");
3325 /* "[Ra], 1/2/4" or "[Ra], -1/-2/-4"
3326 The 1/2/4 or -1/-2/-4 have been displayed in nds32.md.
3327 We only need to deal with register Ra. */
3328 fprintf (stream
, "[%s]", reg_names
[REGNO (op0
)]);
3332 /* The control flow is not supposed to be here. */
3340 /* Generally, output_addr_const () is able to handle most cases.
3341 We want to see what CODE could appear,
3342 so we use gcc_unreachable() to stop it. */
3349 /* -- Assembler Commands for Exception Regions. */
3352 nds32_dwarf_register_span (rtx reg
)
3354 rtx dwarf_high
, dwarf_low
;
3359 mode
= GET_MODE (reg
);
3360 regno
= REGNO (reg
);
3362 /* We need to adjust dwarf register information for floating-point registers
3363 rather than using default register number mapping. */
3364 if (regno
>= NDS32_FIRST_FPR_REGNUM
3365 && regno
<= NDS32_LAST_FPR_REGNUM
)
3367 if (mode
== DFmode
|| mode
== SCmode
)
3369 /* By default, GCC maps increasing register numbers to increasing
3370 memory locations, but paired FPRs in NDS32 target are always
3376 We must return parallel rtx to represent such layout. */
3377 dwarf_high
= gen_rtx_REG (word_mode
, regno
);
3378 dwarf_low
= gen_rtx_REG (word_mode
, regno
+ 1);
3379 return gen_rtx_PARALLEL (VOIDmode
,
3380 gen_rtvec (2, dwarf_low
, dwarf_high
));
3382 else if (mode
== DCmode
)
3384 rtx dwarf_high_re
= gen_rtx_REG (word_mode
, regno
);
3385 rtx dwarf_low_re
= gen_rtx_REG (word_mode
, regno
+ 1);
3386 rtx dwarf_high_im
= gen_rtx_REG (word_mode
, regno
);
3387 rtx dwarf_low_im
= gen_rtx_REG (word_mode
, regno
+ 1);
3388 return gen_rtx_PARALLEL (VOIDmode
,
3389 gen_rtvec (4, dwarf_low_re
, dwarf_high_re
,
3390 dwarf_high_im
, dwarf_low_im
));
3392 else if (mode
== SFmode
|| mode
== SImode
)
3394 /* Create new dwarf information with adjusted register number. */
3395 dwarf_single
= gen_rtx_REG (word_mode
, regno
);
3396 return gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (1, dwarf_single
));
3400 /* We should not be here. */
3408 /* Map internal gcc register numbers to DWARF2 register numbers. */
3411 nds32_dbx_register_number (unsigned int regno
)
3413 /* The nds32 port in GDB maintains a mapping between dwarf register
3414 number and displayed register name. For backward compatibility to
3415 previous toolchain, currently our gdb still has four registers
3416 (d0.l, d0.h, d1.l, and d1.h) between GPR and FPR while compiler
3417 does not count those four registers in its register number table.
3418 So we have to add 4 on its register number and then create new
3419 dwarf information. Hopefully we can discard such workaround
3421 if (NDS32_IS_FPR_REGNUM (regno
))
3428 /* Defining target-specific uses of __attribute__. */
3430 /* Add some checking after merging attributes. */
3432 nds32_merge_decl_attributes (tree olddecl
, tree newdecl
)
3434 tree combined_attrs
;
3436 /* Create combined attributes. */
3437 combined_attrs
= merge_attributes (DECL_ATTRIBUTES (olddecl
),
3438 DECL_ATTRIBUTES (newdecl
));
3440 /* Since newdecl is acutally a duplicate of olddecl,
3441 we can take olddecl for some operations. */
3442 if (TREE_CODE (olddecl
) == FUNCTION_DECL
)
3444 /* Check isr-specific attributes conflict. */
3445 nds32_check_isr_attrs_conflict (olddecl
, combined_attrs
);
3448 return combined_attrs
;
3451 /* Add some checking when inserting attributes. */
3453 nds32_insert_attributes (tree decl
, tree
*attributes
)
3455 /* For function declaration, we need to check isr-specific attributes:
3456 1. Call nds32_check_isr_attrs_conflict() to check any conflict.
3457 2. Check valid integer value for interrupt/exception.
3458 3. Check valid integer value for reset.
3459 4. Check valid function for nmi/warm. */
3460 if (TREE_CODE (decl
) == FUNCTION_DECL
)
3463 tree intr
, excp
, reset
;
3465 /* Pick up function attributes. */
3466 func_attrs
= *attributes
;
3468 /* 1. Call nds32_check_isr_attrs_conflict() to check any conflict. */
3469 nds32_check_isr_attrs_conflict (decl
, func_attrs
);
3471 /* Now we are starting to check valid id value
3472 for interrupt/exception/reset.
3473 Note that we ONLY check its validity here.
3474 To construct isr vector information, it is still performed
3475 by nds32_construct_isr_vectors_information(). */
3476 intr
= lookup_attribute ("interrupt", func_attrs
);
3477 excp
= lookup_attribute ("exception", func_attrs
);
3478 reset
= lookup_attribute ("reset", func_attrs
);
3482 /* Deal with interrupt/exception. */
3484 unsigned int lower_bound
, upper_bound
;
3486 /* The way to handle interrupt or exception is the same,
3487 we just need to take care of actual vector number.
3488 For interrupt(0..63), the actual vector number is (9..72).
3489 For exception(1..8), the actual vector number is (1..8). */
3490 lower_bound
= (intr
) ? (0) : (1);
3491 upper_bound
= (intr
) ? (63) : (8);
3493 /* Prepare id list so that we can traverse id value. */
3494 id_list
= (intr
) ? (TREE_VALUE (intr
)) : (TREE_VALUE (excp
));
3496 /* 2. Check valid integer value for interrupt/exception. */
3501 /* Pick up each vector id value. */
3502 id
= TREE_VALUE (id_list
);
3503 /* Issue error if it is not a valid integer value. */
3504 if (TREE_CODE (id
) != INTEGER_CST
3505 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3506 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3507 error ("invalid id value for interrupt/exception attribute");
3509 /* Advance to next id. */
3510 id_list
= TREE_CHAIN (id_list
);
3515 /* Deal with reset. */
3519 unsigned int lower_bound
;
3520 unsigned int upper_bound
;
3522 /* Prepare id_list and identify id value so that
3523 we can check if total number of vectors is valid. */
3524 id_list
= TREE_VALUE (reset
);
3525 id
= TREE_VALUE (id_list
);
3527 /* The maximum numbers for user's interrupt is 64. */
3531 /* 3. Check valid integer value for reset. */
3532 if (TREE_CODE (id
) != INTEGER_CST
3533 || wi::ltu_p (wi::to_wide (id
), lower_bound
)
3534 || wi::gtu_p (wi::to_wide (id
), upper_bound
))
3535 error ("invalid id value for reset attribute");
3537 /* 4. Check valid function for nmi/warm. */
3538 nmi
= lookup_attribute ("nmi", func_attrs
);
3539 warm
= lookup_attribute ("warm", func_attrs
);
3541 if (nmi
!= NULL_TREE
)
3546 nmi_func_list
= TREE_VALUE (nmi
);
3547 nmi_func
= TREE_VALUE (nmi_func_list
);
3549 /* Issue error if it is not a valid nmi function. */
3550 if (TREE_CODE (nmi_func
) != IDENTIFIER_NODE
)
3551 error ("invalid nmi function for reset attribute");
3554 if (warm
!= NULL_TREE
)
3556 tree warm_func_list
;
3559 warm_func_list
= TREE_VALUE (warm
);
3560 warm_func
= TREE_VALUE (warm_func_list
);
3562 /* Issue error if it is not a valid warm function. */
3563 if (TREE_CODE (warm_func
) != IDENTIFIER_NODE
)
3564 error ("invalid warm function for reset attribute");
3569 /* No interrupt, exception, or reset attribute is set. */
3576 nds32_option_pragma_parse (tree args ATTRIBUTE_UNUSED
,
3577 tree pop_target ATTRIBUTE_UNUSED
)
3579 /* Currently, we do not parse any pragma target by ourself,
3580 so just simply return false. */
3585 nds32_option_override (void)
3587 /* After all the command options have been parsed,
3588 we shall deal with some flags for changing compiler settings. */
3590 /* At first, we check if we have to strictly
3591 set some flags based on ISA family. */
3594 /* Under V2 ISA, we need to strictly disable TARGET_V3PUSH. */
3595 target_flags
&= ~MASK_V3PUSH
;
3599 /* Under V3 ISA, currently nothing should be strictly set. */
3603 /* Under V3M ISA, we need to strictly enable TARGET_REDUCED_REGS. */
3604 target_flags
|= MASK_REDUCED_REGS
;
3605 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF. */
3606 target_flags
&= ~MASK_EXT_PERF
;
3607 /* Under V3M ISA, we need to strictly disable TARGET_EXT_PERF2. */
3608 target_flags
&= ~MASK_EXT_PERF2
;
3609 /* Under V3M ISA, we need to strictly disable TARGET_EXT_STRING. */
3610 target_flags
&= ~MASK_EXT_STRING
;
3613 /* See if we are using reduced-set registers:
3614 $r0~$r5, $r6~$r10, $r15, $r28, $r29, $r30, $r31
3615 If so, we must forbid using $r11~$r14, $r16~$r27. */
3616 if (TARGET_REDUCED_REGS
)
3620 /* Prevent register allocator from
3621 choosing it as doing register allocation. */
3622 for (r
= 11; r
<= 14; r
++)
3623 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3624 for (r
= 16; r
<= 27; r
++)
3625 fixed_regs
[r
] = call_used_regs
[r
] = 1;
3630 /* Under no 16 bit ISA, we need to strictly disable TARGET_V3PUSH. */
3631 target_flags
&= ~MASK_V3PUSH
;
3634 if (TARGET_HARD_FLOAT
&& !(TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
))
3636 if (nds32_arch_option
== ARCH_V3S
|| nds32_arch_option
== ARCH_V3F
)
3637 error ("Disable FPU ISA, "
3638 "the ABI option must be enable '-mfloat-abi=soft'");
3640 error ("'-mabi=2fp+' option only support when FPU available, "
3641 "must be enable '-mext-fpu-sp' or '-mext-fpu-dp'");
3644 /* Currently, we don't support PIC code generation yet. */
3646 sorry ("position-independent code not supported");
3648 nds32_register_passes ();
3652 /* Miscellaneous Parameters. */
3655 nds32_md_asm_adjust (vec
<rtx
> &outputs ATTRIBUTE_UNUSED
,
3656 vec
<rtx
> &inputs ATTRIBUTE_UNUSED
,
3657 vec
<const char *> &constraints ATTRIBUTE_UNUSED
,
3658 vec
<rtx
> &clobbers
, HARD_REG_SET
&clobbered_regs
)
3660 clobbers
.safe_push (gen_rtx_REG (SImode
, TA_REGNUM
));
3661 SET_HARD_REG_BIT (clobbered_regs
, TA_REGNUM
);
3666 nds32_init_builtins (void)
3668 nds32_init_builtins_impl ();
3672 nds32_builtin_decl (unsigned code
, bool initialize_p
)
3674 /* Implement in nds32-intrinsic.c. */
3675 return nds32_builtin_decl_impl (code
, initialize_p
);
3679 nds32_expand_builtin (tree exp
,
3685 return nds32_expand_builtin_impl (exp
, target
, subtarget
, mode
, ignore
);
3689 /* ------------------------------------------------------------------------ */
3691 /* PART 4: Implemet extern function definitions,
3692 the prototype is in nds32-protos.h. */
3694 /* Run-time Target Specification. */
3697 nds32_cpu_cpp_builtins(struct cpp_reader
*pfile
)
3699 #define builtin_define(TXT) cpp_define (pfile, TXT)
3700 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
3701 builtin_define ("__nds32__");
3702 builtin_define ("__NDS32__");
3704 if (TARGET_HARD_FLOAT
)
3705 builtin_define ("__NDS32_ABI_2FP_PLUS__");
3707 builtin_define ("__NDS32_ABI_2__");
3710 builtin_define ("__NDS32_ISA_V2__");
3712 builtin_define ("__NDS32_ISA_V3__");
3714 builtin_define ("__NDS32_ISA_V3M__");
3716 if (TARGET_FPU_SINGLE
)
3717 builtin_define ("__NDS32_EXT_FPU_SP__");
3718 if (TARGET_FPU_DOUBLE
)
3719 builtin_define ("__NDS32_EXT_FPU_DP__");
3721 if (TARGET_EXT_FPU_FMA
)
3722 builtin_define ("__NDS32_EXT_FPU_FMA__");
3723 if (NDS32_EXT_FPU_DOT_E
)
3724 builtin_define ("__NDS32_EXT_FPU_DOT_E__");
3725 if (TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
3727 switch (nds32_fp_regnum
)
3731 builtin_define ("__NDS32_EXT_FPU_CONFIG_0__");
3735 builtin_define ("__NDS32_EXT_FPU_CONFIG_1__");
3739 builtin_define ("__NDS32_EXT_FPU_CONFIG_2__");
3743 builtin_define ("__NDS32_EXT_FPU_CONFIG_3__");
3750 if (TARGET_BIG_ENDIAN
)
3751 builtin_define ("__NDS32_EB__");
3753 builtin_define ("__NDS32_EL__");
3755 if (TARGET_REDUCED_REGS
)
3756 builtin_define ("__NDS32_REDUCED_REGS__");
3758 builtin_define ("__NDS32_CMOV__");
3759 if (TARGET_EXT_PERF
)
3760 builtin_define ("__NDS32_EXT_PERF__");
3761 if (TARGET_EXT_PERF2
)
3762 builtin_define ("__NDS32_EXT_PERF2__");
3763 if (TARGET_EXT_STRING
)
3764 builtin_define ("__NDS32_EXT_STRING__");
3766 builtin_define ("__NDS32_16_BIT__");
3767 if (TARGET_GP_DIRECT
)
3768 builtin_define ("__NDS32_GP_DIRECT__");
3770 builtin_define ("__NDS32_VH__");
3772 if (TARGET_BIG_ENDIAN
)
3773 builtin_define ("__big_endian__");
3775 builtin_assert ("cpu=nds32");
3776 builtin_assert ("machine=nds32");
3778 if (TARGET_HARD_FLOAT
)
3779 builtin_define ("__NDS32_ABI_2FP_PLUS");
3781 builtin_define ("__NDS32_ABI_2");
3783 #undef builtin_define
3784 #undef builtin_assert
3788 /* Defining Data Structures for Per-function Information. */
3791 nds32_init_expanders (void)
3793 /* Arrange to initialize and mark the machine per-function status. */
3794 init_machine_status
= nds32_init_machine_status
;
3798 /* Register Usage. */
3800 /* -- Order of Allocation of Registers. */
3803 nds32_adjust_reg_alloc_order (void)
3805 const int nds32_reg_alloc_order
[] = REG_ALLOC_ORDER
;
3807 /* Copy the default register allocation order, which is designed
3808 to optimize for code size. */
3809 memcpy(reg_alloc_order
, nds32_reg_alloc_order
, sizeof (reg_alloc_order
));
3811 /* Adjust few register allocation order when optimizing for speed. */
3814 memcpy (reg_alloc_order
, nds32_reg_alloc_order_for_speed
,
3815 sizeof (nds32_reg_alloc_order_for_speed
));
3819 /* -- How Values Fit in Registers. */
3822 nds32_hard_regno_nregs (unsigned regno ATTRIBUTE_UNUSED
,
3825 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
);
3828 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3831 nds32_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
3833 if (regno
> FIRST_PSEUDO_REGISTER
)
3836 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
) && NDS32_IS_FPR_REGNUM (regno
))
3838 if (NDS32_IS_EXT_FPR_REGNUM(regno
))
3839 return (NDS32_FPR_REGNO_OK_FOR_DOUBLE(regno
) && (mode
== DFmode
));
3840 else if (mode
== SFmode
|| mode
== SImode
)
3841 return NDS32_FPR_REGNO_OK_FOR_SINGLE (regno
);
3842 else if (mode
== DFmode
)
3843 return NDS32_FPR_REGNO_OK_FOR_DOUBLE (regno
);
3848 /* Restrict double-word quantities to even register pairs. */
3849 if (regno
<= NDS32_LAST_GPR_REGNUM
)
3850 return (targetm
.hard_regno_nregs (regno
, mode
) == 1
3856 /* Implement TARGET_MODES_TIEABLE_P. We can use general registers to
3857 tie QI/HI/SI modes together. */
3860 nds32_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3862 if ((GET_MODE_CLASS (mode1
) == MODE_INT
3863 && GET_MODE_CLASS (mode2
) == MODE_INT
)
3864 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
3865 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
)
3868 if (GET_MODE_SIZE (mode1
) == GET_MODE_SIZE (mode2
))
3870 if ((TARGET_FPU_SINGLE
&& !TARGET_FPU_DOUBLE
)
3871 && (mode1
== DFmode
|| mode2
== DFmode
))
3880 /* Register Classes. */
3883 nds32_regno_reg_class (int regno
)
3885 /* Refer to nds32.h for more register class details. */
3887 if (regno
>= 0 && regno
<= 7)
3889 else if (regno
>= 8 && regno
<= 11)
3891 else if (regno
>= 12 && regno
<= 14)
3893 else if (regno
== 15)
3895 else if (regno
>= 16 && regno
<= 19)
3897 else if (regno
>= 20 && regno
<= 31)
3899 else if (regno
== 32 || regno
== 33)
3901 /* $SFP and $AP is FRAME_REGS in fact, However prevent IRA don't
3902 know how to allocate register for $SFP and $AP, just tell IRA they
3903 are GENERAL_REGS, and ARM do this hack too. */
3904 return GENERAL_REGS
;
3906 else if (regno
>= 34 && regno
<= 97)
3913 /* Stack Layout and Calling Conventions. */
3915 /* -- Basic Stack Layout. */
3918 nds32_dynamic_chain_address (rtx frameaddr
)
3922 /* If -mv3push is specified, we push $fp, $gp, and $lp into stack.
3923 We can access dynamic chain address from stack by [$fp - 12]. */
3924 return plus_constant (Pmode
, frameaddr
, -12);
3928 /* For general case we push $fp and $lp into stack at prologue.
3929 We can access dynamic chain address from stack by [$fp - 8]. */
3930 return plus_constant (Pmode
, frameaddr
, -8);
3935 nds32_return_addr_rtx (int count
,
3943 /* In nds32 ABI design, we can expect that $lp is always available
3944 from stack by [$fp - 4] location. */
3946 addr
= plus_constant (Pmode
, frameaddr
, offset
);
3947 addr
= memory_address (Pmode
, addr
);
3949 return gen_rtx_MEM (Pmode
, addr
);
3952 /* If count == 0, it means we are at current frame,
3953 the return address is $r30 ($lp). */
3954 return get_hard_reg_initial_val (Pmode
, LP_REGNUM
);
3957 /* -- Eliminating Frame Pointer and Arg Pointer. */
3960 nds32_initial_elimination_offset (unsigned int from_reg
, unsigned int to_reg
)
3962 HOST_WIDE_INT offset
;
3964 /* Compute and setup stack frame size.
3965 The result will be in cfun->machine. */
3966 nds32_compute_stack_frame ();
3968 /* Remember to consider
3969 cfun->machine->callee_saved_area_gpr_padding_bytes and
3970 cfun->machine->eh_return_data_regs_size
3971 when calculating offset. */
3972 if (from_reg
== ARG_POINTER_REGNUM
&& to_reg
== STACK_POINTER_REGNUM
)
3974 offset
= (cfun
->machine
->fp_size
3975 + cfun
->machine
->gp_size
3976 + cfun
->machine
->lp_size
3977 + cfun
->machine
->callee_saved_gpr_regs_size
3978 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
3979 + cfun
->machine
->callee_saved_fpr_regs_size
3980 + cfun
->machine
->eh_return_data_regs_size
3981 + cfun
->machine
->local_size
3982 + cfun
->machine
->out_args_size
);
3984 else if (from_reg
== ARG_POINTER_REGNUM
3985 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3989 else if (from_reg
== FRAME_POINTER_REGNUM
3990 && to_reg
== STACK_POINTER_REGNUM
)
3992 offset
= (cfun
->machine
->local_size
+ cfun
->machine
->out_args_size
);
3994 else if (from_reg
== FRAME_POINTER_REGNUM
3995 && to_reg
== HARD_FRAME_POINTER_REGNUM
)
3997 offset
= (-1) * (cfun
->machine
->fp_size
3998 + cfun
->machine
->gp_size
3999 + cfun
->machine
->lp_size
4000 + cfun
->machine
->callee_saved_gpr_regs_size
4001 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4002 + cfun
->machine
->callee_saved_fpr_regs_size
4003 + cfun
->machine
->eh_return_data_regs_size
);
4013 /* -- Passing Arguments in Registers. */
4016 nds32_init_cumulative_args (CUMULATIVE_ARGS
*cum
,
4017 tree fntype ATTRIBUTE_UNUSED
,
4018 rtx libname ATTRIBUTE_UNUSED
,
4019 tree fndecl ATTRIBUTE_UNUSED
,
4020 int n_named_args ATTRIBUTE_UNUSED
)
4022 /* Initial available registers. The values are offset against
4023 NDS32_GPR_ARG_FIRST_REGNUM and NDS32_FPR_ARG_FIRST_REGNUM
4024 for passing arguments. */
4025 cum
->gpr_offset
= 0;
4026 cum
->fpr_offset
= 0;
4029 /* -- Function Entry and Exit. */
4031 /* Function for normal multiple push prologue. */
4033 nds32_expand_prologue (void)
4039 /* Compute and setup stack frame size.
4040 The result will be in cfun->machine. */
4041 nds32_compute_stack_frame ();
4043 /* If this is a variadic function, first we need to push argument
4044 registers that hold the unnamed argument value. */
4045 if (cfun
->machine
->va_args_size
!= 0)
4047 Rb
= cfun
->machine
->va_args_first_regno
;
4048 Re
= cfun
->machine
->va_args_last_regno
;
4049 /* No need to push $fp, $gp, or $lp. */
4050 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, true);
4052 /* We may also need to adjust stack pointer for padding bytes
4053 because varargs may cause $sp not 8-byte aligned. */
4054 if (cfun
->machine
->va_args_area_padding_bytes
)
4056 /* Generate sp adjustment instruction. */
4057 sp_adjust
= cfun
->machine
->va_args_area_padding_bytes
;
4059 nds32_emit_adjust_frame (stack_pointer_rtx
,
4065 /* If the function is 'naked',
4066 we do not have to generate prologue code fragment. */
4067 if (cfun
->machine
->naked_p
)
4070 /* Get callee_first_regno and callee_last_regno. */
4071 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4072 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4074 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4075 to be saved, we don't have to create multiple push instruction.
4076 Otherwise, a multiple push instruction is needed. */
4077 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4078 && cfun
->machine
->fp_size
== 0
4079 && cfun
->machine
->gp_size
== 0
4080 && cfun
->machine
->lp_size
== 0))
4082 /* Create multiple push instruction rtx. */
4083 nds32_emit_stack_push_multiple (
4085 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
,
4089 /* Save eh data registers. */
4090 if (cfun
->machine
->use_eh_return_p
)
4092 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4093 Re
= cfun
->machine
->eh_return_data_last_regno
;
4095 /* No need to push $fp, $gp, or $lp.
4096 Also, this is not variadic arguments push. */
4097 nds32_emit_stack_push_multiple (Rb
, Re
, false, false, false, false);
4100 /* Check frame_pointer_needed to see
4101 if we shall emit fp adjustment instruction. */
4102 if (frame_pointer_needed
)
4104 /* adjust $fp = $sp + ($fp size) + ($gp size) + ($lp size)
4105 + (4 * callee-saved-registers)
4106 + (4 * exception-handling-data-registers)
4107 Note: No need to adjust
4108 cfun->machine->callee_saved_area_gpr_padding_bytes,
4109 because, at this point, stack pointer is just
4110 at the position after push instruction. */
4111 fp_adjust
= cfun
->machine
->fp_size
4112 + cfun
->machine
->gp_size
4113 + cfun
->machine
->lp_size
4114 + cfun
->machine
->callee_saved_gpr_regs_size
4115 + cfun
->machine
->eh_return_data_regs_size
;
4117 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4122 /* Save fpu registers. */
4123 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4125 /* When $sp moved to bottom of stack, we need to check whether
4126 the range of offset in the FPU instruction. */
4127 int fpr_offset
= cfun
->machine
->local_size
4128 + cfun
->machine
->out_args_size
4129 + cfun
->machine
->callee_saved_fpr_regs_size
;
4131 /* Check FPU instruction offset imm14s. */
4132 if (!satisfies_constraint_Is14 (GEN_INT (fpr_offset
)))
4134 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4135 + cfun
->machine
->callee_saved_fpr_regs_size
;
4137 /* Save fpu registers, need to allocate stack space
4138 for fpu callee registers. And now $sp position
4139 on callee saved fpr registers. */
4140 nds32_emit_adjust_frame (stack_pointer_rtx
,
4144 /* Emit fpu store instruction, using [$sp + offset] store
4146 nds32_emit_push_fpr_callee_saved (0);
4148 /* Adjust $sp = $sp - local_size - out_args_size. */
4149 sp_adjust
= cfun
->machine
->local_size
4150 + cfun
->machine
->out_args_size
;
4152 /* Allocate stack space for local size and out args size. */
4153 nds32_emit_adjust_frame (stack_pointer_rtx
,
4159 /* Offset range in Is14, so $sp moved to bottom of stack. */
4161 /* Adjust $sp = $sp - local_size - out_args_size
4162 - callee_saved_area_gpr_padding_bytes
4163 - callee_saved_fpr_regs_size. */
4164 sp_adjust
= cfun
->machine
->local_size
4165 + cfun
->machine
->out_args_size
4166 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4167 + cfun
->machine
->callee_saved_fpr_regs_size
;
4169 nds32_emit_adjust_frame (stack_pointer_rtx
,
4173 /* Emit fpu store instruction, using [$sp + offset] store
4175 int fpr_position
= cfun
->machine
->out_args_size
4176 + cfun
->machine
->local_size
;
4177 nds32_emit_push_fpr_callee_saved (fpr_position
);
4182 /* Adjust $sp = $sp - local_size - out_args_size
4183 - callee_saved_area_gpr_padding_bytes. */
4184 sp_adjust
= cfun
->machine
->local_size
4185 + cfun
->machine
->out_args_size
4186 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4188 /* sp_adjust value may be out of range of the addi instruction,
4189 create alternative add behavior with TA_REGNUM if necessary,
4190 using NEGATIVE value to tell that we are decreasing address. */
4191 nds32_emit_adjust_frame (stack_pointer_rtx
,
4196 /* Prevent the instruction scheduler from
4197 moving instructions across the boundary. */
4198 emit_insn (gen_blockage ());
4201 /* Function for normal multiple pop epilogue. */
4203 nds32_expand_epilogue (bool sibcall_p
)
4208 /* Compute and setup stack frame size.
4209 The result will be in cfun->machine. */
4210 nds32_compute_stack_frame ();
4212 /* Prevent the instruction scheduler from
4213 moving instructions across the boundary. */
4214 emit_insn (gen_blockage ());
4216 /* If the function is 'naked', we do not have to generate
4217 epilogue code fragment BUT 'ret' instruction.
4218 However, if this function is also a variadic function,
4219 we need to create adjust stack pointer before 'ret' instruction. */
4220 if (cfun
->machine
->naked_p
)
4222 /* If this is a variadic function, we do not have to restore argument
4223 registers but need to adjust stack pointer back to previous stack
4224 frame location before return. */
4225 if (cfun
->machine
->va_args_size
!= 0)
4227 /* Generate sp adjustment instruction.
4228 We need to consider padding bytes here. */
4229 sp_adjust
= cfun
->machine
->va_args_size
4230 + cfun
->machine
->va_args_area_padding_bytes
;
4232 nds32_emit_adjust_frame (stack_pointer_rtx
,
4237 /* Generate return instruction by using 'return_internal' pattern.
4238 Make sure this instruction is after gen_blockage(). */
4240 emit_jump_insn (gen_return_internal ());
4244 if (frame_pointer_needed
)
4246 /* Restore fpu registers. */
4247 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4249 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4251 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4252 - (4 * callee-saved-registers)
4253 - (4 * exception-handling-data-registers)
4254 - (4 * callee-saved-gpr-registers padding byte)
4255 - (4 * callee-saved-fpr-registers)
4256 Note: we want to adjust stack pointer
4257 to the position for callee-saved fpr register,
4258 And restore fpu register use .bi instruction to adjust $sp
4259 from callee-saved fpr register to pop instruction. */
4260 sp_adjust
= cfun
->machine
->fp_size
4261 + cfun
->machine
->gp_size
4262 + cfun
->machine
->lp_size
4263 + cfun
->machine
->callee_saved_gpr_regs_size
4264 + cfun
->machine
->eh_return_data_regs_size
4265 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4266 + cfun
->machine
->callee_saved_fpr_regs_size
;
4268 nds32_emit_adjust_frame (stack_pointer_rtx
,
4269 hard_frame_pointer_rtx
,
4272 /* Emit fpu load instruction, using .bi instruction
4273 load fpu registers. */
4274 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4278 /* adjust $sp = $fp - ($fp size) - ($gp size) - ($lp size)
4279 - (4 * callee-saved-registers)
4280 - (4 * exception-handling-data-registers)
4281 Note: No need to adjust
4282 cfun->machine->callee_saved_area_gpr_padding_bytes,
4283 because we want to adjust stack pointer
4284 to the position for pop instruction. */
4285 sp_adjust
= cfun
->machine
->fp_size
4286 + cfun
->machine
->gp_size
4287 + cfun
->machine
->lp_size
4288 + cfun
->machine
->callee_saved_gpr_regs_size
4289 + cfun
->machine
->eh_return_data_regs_size
;
4291 nds32_emit_adjust_frame (stack_pointer_rtx
,
4292 hard_frame_pointer_rtx
,
4298 /* Restore fpu registers. */
4299 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4301 int gpr_padding
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4303 /* Adjust $sp = $sp + local_size + out_args_size. */
4304 sp_adjust
= cfun
->machine
->local_size
4305 + cfun
->machine
->out_args_size
;
4307 nds32_emit_adjust_frame (stack_pointer_rtx
,
4311 /* Emit fpu load instruction, using .bi instruction
4312 load fpu registers, and adjust $sp from callee-saved fpr register
4313 to callee-saved gpr register. */
4314 nds32_emit_pop_fpr_callee_saved (gpr_padding
);
4318 /* If frame pointer is NOT needed,
4319 we cannot calculate the sp adjustment from frame pointer.
4320 Instead, we calculate the adjustment by local_size,
4321 out_args_size, and callee_saved_area_gpr_padding_bytes.
4322 Notice that such sp adjustment value may be out of range,
4323 so we have to deal with it as well. */
4325 /* Adjust $sp = $sp + local_size + out_args_size
4326 + callee_saved_area_gpr_padding_bytes. */
4327 sp_adjust
= cfun
->machine
->local_size
4328 + cfun
->machine
->out_args_size
4329 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
;
4331 nds32_emit_adjust_frame (stack_pointer_rtx
,
4337 /* Restore eh data registers. */
4338 if (cfun
->machine
->use_eh_return_p
)
4340 Rb
= cfun
->machine
->eh_return_data_first_regno
;
4341 Re
= cfun
->machine
->eh_return_data_last_regno
;
4343 /* No need to pop $fp, $gp, or $lp. */
4344 nds32_emit_stack_pop_multiple (Rb
, Re
, false, false, false);
4347 /* Get callee_first_regno and callee_last_regno. */
4348 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4349 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4351 /* If $fp, $gp, $lp, and all callee-save registers are NOT required
4352 to be saved, we don't have to create multiple pop instruction.
4353 Otherwise, a multiple pop instruction is needed. */
4354 if (!(Rb
== SP_REGNUM
&& Re
== SP_REGNUM
4355 && cfun
->machine
->fp_size
== 0
4356 && cfun
->machine
->gp_size
== 0
4357 && cfun
->machine
->lp_size
== 0))
4359 /* Create multiple pop instruction rtx. */
4360 nds32_emit_stack_pop_multiple (
4362 cfun
->machine
->fp_size
, cfun
->machine
->gp_size
, cfun
->machine
->lp_size
);
4365 /* If this is a variadic function, we do not have to restore argument
4366 registers but need to adjust stack pointer back to previous stack
4367 frame location before return. */
4368 if (cfun
->machine
->va_args_size
!= 0)
4370 /* Generate sp adjustment instruction.
4371 We need to consider padding bytes here. */
4372 sp_adjust
= cfun
->machine
->va_args_size
4373 + cfun
->machine
->va_args_area_padding_bytes
;
4375 nds32_emit_adjust_frame (stack_pointer_rtx
,
4380 /* If this function uses __builtin_eh_return, make stack adjustment
4381 for exception handler. */
4382 if (cfun
->machine
->use_eh_return_p
)
4384 /* We need to unwind the stack by the offset computed by
4385 EH_RETURN_STACKADJ_RTX. However, at this point the CFA is
4386 based on SP. Ideally we would update the SP and define the
4387 CFA along the lines of:
4389 SP = SP + EH_RETURN_STACKADJ_RTX
4390 (regnote CFA = SP - EH_RETURN_STACKADJ_RTX)
4392 However the dwarf emitter only understands a constant
4395 The solution chosen here is to use the otherwise $ta ($r15)
4396 as a temporary register to hold the current SP value. The
4397 CFA is described using $ta then SP is modified. */
4402 ta_reg
= gen_rtx_REG (SImode
, TA_REGNUM
);
4404 insn
= emit_move_insn (ta_reg
, stack_pointer_rtx
);
4405 add_reg_note (insn
, REG_CFA_DEF_CFA
, ta_reg
);
4406 RTX_FRAME_RELATED_P (insn
) = 1;
4408 emit_insn (gen_addsi3 (stack_pointer_rtx
,
4410 EH_RETURN_STACKADJ_RTX
));
4412 /* Ensure the assignment to $ta does not get optimized away. */
4416 /* Generate return instruction. */
4418 emit_jump_insn (gen_return_internal ());
4421 /* Function for v3push prologue. */
4423 nds32_expand_prologue_v3push (void)
4430 /* Compute and setup stack frame size.
4431 The result will be in cfun->machine. */
4432 nds32_compute_stack_frame ();
4434 if (cfun
->machine
->callee_saved_gpr_regs_size
> 0)
4435 df_set_regs_ever_live (FP_REGNUM
, 1);
4437 /* If the function is 'naked',
4438 we do not have to generate prologue code fragment. */
4439 if (cfun
->machine
->naked_p
)
4442 /* Get callee_first_regno and callee_last_regno. */
4443 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4444 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4446 /* Calculate sp_adjust first to test if 'push25 Re,imm8u' is available,
4447 where imm8u has to be 8-byte alignment. */
4448 sp_adjust
= cfun
->machine
->local_size
4449 + cfun
->machine
->out_args_size
4450 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4451 + cfun
->machine
->callee_saved_fpr_regs_size
;
4453 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4454 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
))
4456 /* We can use 'push25 Re,imm8u'. */
4458 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4459 the pattern 'stack_v3push' is implemented in nds32.md. */
4460 nds32_emit_stack_v3push (Rb
, Re
, sp_adjust
);
4462 /* Save fpu registers. */
4463 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4465 /* Calculate fpr position. */
4466 int fpr_position
= cfun
->machine
->local_size
4467 + cfun
->machine
->out_args_size
;
4468 /* Emit fpu store instruction, using [$sp + offset] store
4470 nds32_emit_push_fpr_callee_saved (fpr_position
);
4473 /* Check frame_pointer_needed to see
4474 if we shall emit fp adjustment instruction. */
4475 if (frame_pointer_needed
)
4477 /* adjust $fp = $sp + 4 ($fp size)
4480 + (4 * n) (callee-saved registers)
4481 + sp_adjust ('push25 Re,imm8u')
4482 Note: Since we use 'push25 Re,imm8u',
4483 the position of stack pointer is further
4484 changed after push instruction.
4485 Hence, we need to take sp_adjust value
4486 into consideration. */
4487 fp_adjust
= cfun
->machine
->fp_size
4488 + cfun
->machine
->gp_size
4489 + cfun
->machine
->lp_size
4490 + cfun
->machine
->callee_saved_gpr_regs_size
4493 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4500 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4502 /* Calculate fpr space. */
4503 fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4504 + cfun
->machine
->callee_saved_fpr_regs_size
;
4506 /* We have to use 'push25 Re, fpr_space', to pre-allocate
4507 callee saved fpr registers space. */
4508 nds32_emit_stack_v3push (Rb
, Re
, fpr_space
);
4509 nds32_emit_push_fpr_callee_saved (0);
4513 /* We have to use 'push25 Re,0' and
4514 expand one more instruction to adjust $sp later. */
4516 /* nds32_emit_stack_v3push(last_regno, sp_adjust),
4517 the pattern 'stack_v3push' is implemented in nds32.md. */
4518 nds32_emit_stack_v3push (Rb
, Re
, 0);
4521 /* Check frame_pointer_needed to see
4522 if we shall emit fp adjustment instruction. */
4523 if (frame_pointer_needed
)
4525 /* adjust $fp = $sp + 4 ($fp size)
4528 + (4 * n) (callee-saved registers)
4529 Note: Since we use 'push25 Re,0',
4530 the stack pointer is just at the position
4531 after push instruction.
4532 No need to take sp_adjust into consideration. */
4533 fp_adjust
= cfun
->machine
->fp_size
4534 + cfun
->machine
->gp_size
4535 + cfun
->machine
->lp_size
4536 + cfun
->machine
->callee_saved_gpr_regs_size
;
4538 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4540 /* We use 'push25 Re, fpr_space', the $sp is
4541 on callee saved fpr position, so need to consider
4543 fp_adjust
= fp_adjust
+ fpr_space
;
4546 nds32_emit_adjust_frame (hard_frame_pointer_rtx
,
4551 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4553 /* We use 'push25 Re, fpr_space',
4554 the $sp is on callee saved fpr position,
4555 no need to consider fpr space. */
4556 sp_adjust
= sp_adjust
- fpr_space
;
4559 /* Because we use 'push25 Re,0',
4560 we need to expand one more instruction to adjust $sp.
4561 using NEGATIVE value to tell that we are decreasing address. */
4562 nds32_emit_adjust_frame (stack_pointer_rtx
,
4567 /* Prevent the instruction scheduler from
4568 moving instructions across the boundary. */
4569 emit_insn (gen_blockage ());
4572 /* Function for v3pop epilogue. */
4574 nds32_expand_epilogue_v3pop (bool sibcall_p
)
4579 /* Compute and setup stack frame size.
4580 The result will be in cfun->machine. */
4581 nds32_compute_stack_frame ();
4583 /* Prevent the instruction scheduler from
4584 moving instructions across the boundary. */
4585 emit_insn (gen_blockage ());
4587 /* If the function is 'naked', we do not have to generate
4588 epilogue code fragment BUT 'ret' instruction. */
4589 if (cfun
->machine
->naked_p
)
4591 /* Generate return instruction by using 'return_internal' pattern.
4592 Make sure this instruction is after gen_blockage(). */
4594 emit_jump_insn (gen_return_internal ());
4598 /* Get callee_first_regno and callee_last_regno. */
4599 Rb
= cfun
->machine
->callee_saved_first_gpr_regno
;
4600 Re
= cfun
->machine
->callee_saved_last_gpr_regno
;
4602 /* Calculate sp_adjust first to test if 'pop25 Re,imm8u' is available,
4603 where imm8u has to be 8-byte alignment. */
4604 sp_adjust
= cfun
->machine
->local_size
4605 + cfun
->machine
->out_args_size
4606 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4607 + cfun
->machine
->callee_saved_fpr_regs_size
;
4609 /* We have to consider alloca issue as well.
4610 If the function does call alloca(), the stack pointer is not fixed.
4611 In that case, we cannot use 'pop25 Re,imm8u' directly.
4612 We have to caculate stack pointer from frame pointer
4613 and then use 'pop25 Re,0'.
4614 Of course, the frame_pointer_needed should be nonzero
4615 if the function calls alloca(). */
4616 if (satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4617 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4618 && !cfun
->calls_alloca
)
4620 /* Restore fpu registers. */
4621 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4623 int fpr_position
= cfun
->machine
->local_size
4624 + cfun
->machine
->out_args_size
;
4625 /* Emit fpu load instruction, using [$sp + offset] restore
4627 nds32_emit_v3pop_fpr_callee_saved (fpr_position
);
4630 /* We can use 'pop25 Re,imm8u'. */
4632 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4633 the pattern 'stack_v3pop' is implementad in nds32.md. */
4634 nds32_emit_stack_v3pop (Rb
, Re
, sp_adjust
);
4638 /* We have to use 'pop25 Re,0', and prior to it,
4639 we must expand one more instruction to adjust $sp. */
4641 if (frame_pointer_needed
)
4643 /* adjust $sp = $fp - 4 ($fp size)
4646 - (4 * n) (callee-saved registers)
4647 Note: No need to adjust
4648 cfun->machine->callee_saved_area_gpr_padding_bytes,
4649 because we want to adjust stack pointer
4650 to the position for pop instruction. */
4651 sp_adjust
= cfun
->machine
->fp_size
4652 + cfun
->machine
->gp_size
4653 + cfun
->machine
->lp_size
4654 + cfun
->machine
->callee_saved_gpr_regs_size
;
4656 /* Restore fpu registers. */
4657 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4659 /* Set $sp to callee saved fpr position, we need to restore
4661 sp_adjust
= sp_adjust
4662 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4663 + cfun
->machine
->callee_saved_fpr_regs_size
;
4665 nds32_emit_adjust_frame (stack_pointer_rtx
,
4666 hard_frame_pointer_rtx
,
4669 /* Emit fpu load instruction, using [$sp + offset] restore
4671 nds32_emit_v3pop_fpr_callee_saved (0);
4675 nds32_emit_adjust_frame (stack_pointer_rtx
,
4676 hard_frame_pointer_rtx
,
4682 /* If frame pointer is NOT needed,
4683 we cannot calculate the sp adjustment from frame pointer.
4684 Instead, we calculate the adjustment by local_size,
4685 out_args_size, and callee_saved_area_padding_bytes.
4686 Notice that such sp adjustment value may be out of range,
4687 so we have to deal with it as well. */
4689 /* Adjust $sp = $sp + local_size + out_args_size
4690 + callee_saved_area_gpr_padding_bytes
4691 + callee_saved_fpr_regs_size. */
4692 sp_adjust
= cfun
->machine
->local_size
4693 + cfun
->machine
->out_args_size
4694 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4695 + cfun
->machine
->callee_saved_fpr_regs_size
;
4697 /* Restore fpu registers. */
4698 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4700 /* Set $sp to callee saved fpr position, we need to restore
4702 sp_adjust
= sp_adjust
4703 - cfun
->machine
->callee_saved_area_gpr_padding_bytes
4704 - cfun
->machine
->callee_saved_fpr_regs_size
;
4706 nds32_emit_adjust_frame (stack_pointer_rtx
,
4710 /* Emit fpu load instruction, using [$sp + offset] restore
4712 nds32_emit_v3pop_fpr_callee_saved (0);
4716 /* sp_adjust value may be out of range of the addi instruction,
4717 create alternative add behavior with TA_REGNUM if necessary,
4718 using POSITIVE value to tell that we are increasing
4720 nds32_emit_adjust_frame (stack_pointer_rtx
,
4726 if (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)
4728 /* We have fpr need to restore, so $sp is set on callee saved fpr
4729 position. And we use 'pop25 Re, fpr_space' to adjust $sp. */
4730 int fpr_space
= cfun
->machine
->callee_saved_area_gpr_padding_bytes
4731 + cfun
->machine
->callee_saved_fpr_regs_size
;
4732 nds32_emit_stack_v3pop (Rb
, Re
, fpr_space
);
4736 /* nds32_emit_stack_v3pop(last_regno, sp_adjust),
4737 the pattern 'stack_v3pop' is implementad in nds32.md. */
4738 nds32_emit_stack_v3pop (Rb
, Re
, 0);
4741 /* Generate return instruction. */
4742 emit_jump_insn (gen_pop25return ());
4745 /* Return nonzero if this function is known to have a null epilogue.
4746 This allows the optimizer to omit jumps to jumps if no stack
4749 nds32_can_use_return_insn (void)
4753 /* Prior to reloading, we can't tell how many registers must be saved.
4754 Thus we can not determine whether this function has null epilogue. */
4755 if (!reload_completed
)
4758 sp_adjust
= cfun
->machine
->local_size
4759 + cfun
->machine
->out_args_size
4760 + cfun
->machine
->callee_saved_area_gpr_padding_bytes
4761 + cfun
->machine
->callee_saved_fpr_regs_size
;
4762 if (!cfun
->machine
->fp_as_gp_p
4763 && satisfies_constraint_Iu08 (GEN_INT (sp_adjust
))
4764 && NDS32_DOUBLE_WORD_ALIGN_P (sp_adjust
)
4765 && !cfun
->calls_alloca
4766 && NDS32_V3PUSH_AVAILABLE_P
4767 && !(TARGET_HARD_FLOAT
4768 && (cfun
->machine
->callee_saved_first_fpr_regno
!= SP_REGNUM
)))
4771 /* If no stack was created, two conditions must be satisfied:
4772 1. This is a naked function.
4773 So there is no callee-saved, local size, or outgoing size.
4774 2. This is NOT a variadic function.
4775 So there is no pushing arguement registers into the stack. */
4776 return (cfun
->machine
->naked_p
&& (cfun
->machine
->va_args_size
== 0));
4780 nds32_case_vector_shorten_mode (int min_offset
, int max_offset
,
4781 rtx body ATTRIBUTE_UNUSED
)
4783 if (min_offset
< 0 || max_offset
>= 0x2000)
4787 /* The jump table maybe need to 2 byte alignment,
4788 so reserved 1 byte for check max_offset. */
4789 if (max_offset
>= 0xff)
4796 /* ------------------------------------------------------------------------ */
4798 /* Return alignment for the label. */
4800 nds32_target_alignment (rtx_insn
*label
)
4804 if (!NDS32_ALIGN_P ())
4807 insn
= next_active_insn (label
);
4809 /* Always align to 4 byte when first instruction after label is jump
4810 instruction since length for that might changed, so let's always align
4811 it for make sure we don't lose any perfomance here. */
4813 || (get_attr_length (insn
) == 2
4814 && !JUMP_P (insn
) && !CALL_P (insn
)))
4820 /* Return alignment for data. */
4822 nds32_data_alignment (tree data
,
4823 unsigned int basic_align
)
4825 if ((basic_align
< BITS_PER_WORD
)
4826 && (TREE_CODE (data
) == ARRAY_TYPE
4827 || TREE_CODE (data
) == UNION_TYPE
4828 || TREE_CODE (data
) == RECORD_TYPE
))
4829 return BITS_PER_WORD
;
4834 /* Return alignment for constant value. */
4835 static HOST_WIDE_INT
4836 nds32_constant_alignment (const_tree constant
,
4837 HOST_WIDE_INT basic_align
)
4839 /* Make string literal and constant for constructor to word align. */
4840 if (((TREE_CODE (constant
) == STRING_CST
4841 || TREE_CODE (constant
) == CONSTRUCTOR
4842 || TREE_CODE (constant
) == UNION_TYPE
4843 || TREE_CODE (constant
) == RECORD_TYPE
4844 || TREE_CODE (constant
) == ARRAY_TYPE
)
4845 && basic_align
< BITS_PER_WORD
))
4846 return BITS_PER_WORD
;
4851 /* Return alignment for local variable. */
4853 nds32_local_alignment (tree local ATTRIBUTE_UNUSED
,
4854 unsigned int basic_align
)
4856 bool at_least_align_to_word
= false;
4857 /* Make local array, struct and union at least align to word for make
4858 sure it can unroll memcpy when initialize by constant. */
4859 switch (TREE_CODE (local
))
4864 at_least_align_to_word
= true;
4867 at_least_align_to_word
= false;
4870 if (at_least_align_to_word
4871 && (basic_align
< BITS_PER_WORD
))
4872 return BITS_PER_WORD
;
4878 nds32_split_double_word_load_store_p(rtx
*operands
, bool load_p
)
4880 rtx mem
= load_p
? operands
[1] : operands
[0];
4881 /* Do split at split2 if -O0 or schedule 2 not enable. */
4882 if (optimize
== 0 || !flag_schedule_insns_after_reload
)
4883 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4885 /* Split double word load store after copy propgation. */
4886 if (current_pass
== NULL
)
4889 const char *pass_name
= current_pass
->name
;
4890 if (pass_name
&& ((strcmp (pass_name
, "split4") == 0)
4891 || (strcmp (pass_name
, "split5") == 0)))
4892 return !satisfies_constraint_Da (mem
) || MEM_VOLATILE_P (mem
);
4898 nds32_use_blocks_for_constant_p (machine_mode mode
,
4899 const_rtx x ATTRIBUTE_UNUSED
)
4901 if ((TARGET_FPU_SINGLE
|| TARGET_FPU_DOUBLE
)
4902 && (mode
== DFmode
|| mode
== SFmode
))
4908 /* ------------------------------------------------------------------------ */
4910 /* PART 5: Initialize target hook structure and definitions. */
4912 /* Controlling the Compilation Driver. */
4915 /* Run-time Target Specification. */
4918 /* Defining Data Structures for Per-function Information. */
4921 /* Storage Layout. */
4923 #undef TARGET_PROMOTE_FUNCTION_MODE
4924 #define TARGET_PROMOTE_FUNCTION_MODE \
4925 default_promote_function_mode_always_promote
4927 #undef TARGET_EXPAND_TO_RTL_HOOK
4928 #define TARGET_EXPAND_TO_RTL_HOOK nds32_expand_to_rtl_hook
4930 #undef TARGET_CONSTANT_ALIGNMENT
4931 #define TARGET_CONSTANT_ALIGNMENT nds32_constant_alignment
4934 /* Layout of Source Language Data Types. */
4937 /* Register Usage. */
4939 /* -- Basic Characteristics of Registers. */
4941 #undef TARGET_CONDITIONAL_REGISTER_USAGE
4942 #define TARGET_CONDITIONAL_REGISTER_USAGE nds32_conditional_register_usage
4944 /* -- Order of Allocation of Registers. */
4946 /* -- How Values Fit in Registers. */
4948 #undef TARGET_HARD_REGNO_NREGS
4949 #define TARGET_HARD_REGNO_NREGS nds32_hard_regno_nregs
4951 #undef TARGET_HARD_REGNO_MODE_OK
4952 #define TARGET_HARD_REGNO_MODE_OK nds32_hard_regno_mode_ok
4954 #undef TARGET_MODES_TIEABLE_P
4955 #define TARGET_MODES_TIEABLE_P nds32_modes_tieable_p
4957 /* -- Handling Leaf Functions. */
4959 /* -- Registers That Form a Stack. */
4962 /* Register Classes. */
4964 #undef TARGET_CLASS_MAX_NREGS
4965 #define TARGET_CLASS_MAX_NREGS nds32_class_max_nregs
4967 #undef TARGET_REGISTER_PRIORITY
4968 #define TARGET_REGISTER_PRIORITY nds32_register_priority
4970 #undef TARGET_CAN_CHANGE_MODE_CLASS
4971 #define TARGET_CAN_CHANGE_MODE_CLASS nds32_can_change_mode_class
4974 /* Obsolete Macros for Defining Constraints. */
4977 /* Stack Layout and Calling Conventions. */
4979 /* -- Basic Stack Layout. */
4981 /* -- Exception Handling Support. */
4983 /* -- Specifying How Stack Checking is Done. */
4985 /* -- Registers That Address the Stack Frame. */
4987 /* -- Eliminating Frame Pointer and Arg Pointer. */
4989 #undef TARGET_CAN_ELIMINATE
4990 #define TARGET_CAN_ELIMINATE nds32_can_eliminate
4992 /* -- Passing Function Arguments on the Stack. */
4994 /* -- Passing Arguments in Registers. */
4996 #undef TARGET_FUNCTION_ARG
4997 #define TARGET_FUNCTION_ARG nds32_function_arg
4999 #undef TARGET_MUST_PASS_IN_STACK
5000 #define TARGET_MUST_PASS_IN_STACK nds32_must_pass_in_stack
5002 #undef TARGET_ARG_PARTIAL_BYTES
5003 #define TARGET_ARG_PARTIAL_BYTES nds32_arg_partial_bytes
5005 #undef TARGET_FUNCTION_ARG_ADVANCE
5006 #define TARGET_FUNCTION_ARG_ADVANCE nds32_function_arg_advance
5008 #undef TARGET_FUNCTION_ARG_BOUNDARY
5009 #define TARGET_FUNCTION_ARG_BOUNDARY nds32_function_arg_boundary
5011 /* -- How Scalar Function Values Are Returned. */
5013 #undef TARGET_FUNCTION_VALUE
5014 #define TARGET_FUNCTION_VALUE nds32_function_value
5016 #undef TARGET_LIBCALL_VALUE
5017 #define TARGET_LIBCALL_VALUE nds32_libcall_value
5019 #undef TARGET_FUNCTION_VALUE_REGNO_P
5020 #define TARGET_FUNCTION_VALUE_REGNO_P nds32_function_value_regno_p
5022 /* -- How Large Values Are Returned. */
5024 #undef TARGET_RETURN_IN_MEMORY
5025 #define TARGET_RETURN_IN_MEMORY nds32_return_in_memory
5027 /* -- Caller-Saves Register Allocation. */
5029 /* -- Function Entry and Exit. */
5031 #undef TARGET_ASM_FUNCTION_PROLOGUE
5032 #define TARGET_ASM_FUNCTION_PROLOGUE nds32_asm_function_prologue
5034 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
5035 #define TARGET_ASM_FUNCTION_END_PROLOGUE nds32_asm_function_end_prologue
5037 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
5038 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE nds32_asm_function_begin_epilogue
5040 #undef TARGET_ASM_FUNCTION_EPILOGUE
5041 #define TARGET_ASM_FUNCTION_EPILOGUE nds32_asm_function_epilogue
5043 #undef TARGET_ASM_OUTPUT_MI_THUNK
5044 #define TARGET_ASM_OUTPUT_MI_THUNK nds32_asm_output_mi_thunk
5046 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5047 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
5049 /* -- Generating Code for Profiling. */
5051 /* -- Permitting tail calls. */
5053 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
5054 #define TARGET_FUNCTION_OK_FOR_SIBCALL nds32_function_ok_for_sibcall
5056 #undef TARGET_WARN_FUNC_RETURN
5057 #define TARGET_WARN_FUNC_RETURN nds32_warn_func_return
5059 /* Stack smashing protection. */
5062 /* Implementing the Varargs Macros. */
5064 #undef TARGET_SETUP_INCOMING_VARARGS
5065 #define TARGET_SETUP_INCOMING_VARARGS nds32_setup_incoming_varargs
5067 #undef TARGET_STRICT_ARGUMENT_NAMING
5068 #define TARGET_STRICT_ARGUMENT_NAMING nds32_strict_argument_naming
5071 /* Trampolines for Nested Functions. */
5073 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
5074 #define TARGET_ASM_TRAMPOLINE_TEMPLATE nds32_asm_trampoline_template
5076 #undef TARGET_TRAMPOLINE_INIT
5077 #define TARGET_TRAMPOLINE_INIT nds32_trampoline_init
5080 /* Implicit Calls to Library Routines. */
5083 /* Addressing Modes. */
5085 #undef TARGET_LEGITIMATE_ADDRESS_P
5086 #define TARGET_LEGITIMATE_ADDRESS_P nds32_legitimate_address_p
5089 /* Anchored Addresses. */
5092 /* Condition Code Status. */
5094 /* -- Representation of condition codes using (cc0). */
5096 /* -- Representation of condition codes using registers. */
5098 #undef TARGET_CANONICALIZE_COMPARISON
5099 #define TARGET_CANONICALIZE_COMPARISON nds32_canonicalize_comparison
5101 /* -- Macros to control conditional execution. */
5104 /* Describing Relative Costs of Operations. */
5106 #undef TARGET_REGISTER_MOVE_COST
5107 #define TARGET_REGISTER_MOVE_COST nds32_register_move_cost
5109 #undef TARGET_MEMORY_MOVE_COST
5110 #define TARGET_MEMORY_MOVE_COST nds32_memory_move_cost
5112 #undef TARGET_RTX_COSTS
5113 #define TARGET_RTX_COSTS nds32_rtx_costs
5115 #undef TARGET_ADDRESS_COST
5116 #define TARGET_ADDRESS_COST nds32_address_cost
5119 /* Adjusting the Instruction Scheduler. */
5122 /* Dividing the Output into Sections (Texts, Data, . . . ). */
5124 #undef TARGET_ENCODE_SECTION_INFO
5125 #define TARGET_ENCODE_SECTION_INFO nds32_encode_section_info
5128 /* Position Independent Code. */
5131 /* Defining the Output Assembler Language. */
5133 /* -- The Overall Framework of an Assembler File. */
5135 #undef TARGET_ASM_FILE_START
5136 #define TARGET_ASM_FILE_START nds32_asm_file_start
5137 #undef TARGET_ASM_FILE_END
5138 #define TARGET_ASM_FILE_END nds32_asm_file_end
5140 /* -- Output of Data. */
5142 #undef TARGET_ASM_ALIGNED_HI_OP
5143 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
5145 #undef TARGET_ASM_ALIGNED_SI_OP
5146 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
5148 /* -- Output of Uninitialized Variables. */
5150 /* -- Output and Generation of Labels. */
5152 #undef TARGET_ASM_GLOBALIZE_LABEL
5153 #define TARGET_ASM_GLOBALIZE_LABEL nds32_asm_globalize_label
5155 /* -- How Initialization Functions Are Handled. */
5157 /* -- Macros Controlling Initialization Routines. */
5159 /* -- Output of Assembler Instructions. */
5161 #undef TARGET_PRINT_OPERAND
5162 #define TARGET_PRINT_OPERAND nds32_print_operand
5163 #undef TARGET_PRINT_OPERAND_ADDRESS
5164 #define TARGET_PRINT_OPERAND_ADDRESS nds32_print_operand_address
5166 /* -- Output of Dispatch Tables. */
5168 /* -- Assembler Commands for Exception Regions. */
5170 #undef TARGET_DWARF_REGISTER_SPAN
5171 #define TARGET_DWARF_REGISTER_SPAN nds32_dwarf_register_span
5173 /* -- Assembler Commands for Alignment. */
5176 /* Controlling Debugging Information Format. */
5178 /* -- Macros Affecting All Debugging Formats. */
5180 /* -- Specific Options for DBX Output. */
5182 /* -- Open-Ended Hooks for DBX Format. */
5184 /* -- File Names in DBX Format. */
5186 /* -- Macros for DWARF Output. */
5188 /* -- Macros for VMS Debug Format. */
5191 /* Cross Compilation and Floating Point. */
5194 /* Mode Switching Instructions. */
5197 /* Defining target-specific uses of __attribute__. */
5199 #undef TARGET_ATTRIBUTE_TABLE
5200 #define TARGET_ATTRIBUTE_TABLE nds32_attribute_table
5202 #undef TARGET_MERGE_DECL_ATTRIBUTES
5203 #define TARGET_MERGE_DECL_ATTRIBUTES nds32_merge_decl_attributes
5205 #undef TARGET_INSERT_ATTRIBUTES
5206 #define TARGET_INSERT_ATTRIBUTES nds32_insert_attributes
5208 #undef TARGET_OPTION_PRAGMA_PARSE
5209 #define TARGET_OPTION_PRAGMA_PARSE nds32_option_pragma_parse
5211 #undef TARGET_OPTION_OVERRIDE
5212 #define TARGET_OPTION_OVERRIDE nds32_option_override
5215 /* Emulating TLS. */
5218 /* Defining coprocessor specifics for MIPS targets. */
5221 /* Parameters for Precompiled Header Validity Checking. */
5224 /* C++ ABI parameters. */
5227 /* Adding support for named address spaces. */
5230 /* Miscellaneous Parameters. */
5232 #undef TARGET_MD_ASM_ADJUST
5233 #define TARGET_MD_ASM_ADJUST nds32_md_asm_adjust
5235 #undef TARGET_INIT_BUILTINS
5236 #define TARGET_INIT_BUILTINS nds32_init_builtins
5238 #undef TARGET_BUILTIN_DECL
5239 #define TARGET_BUILTIN_DECL nds32_builtin_decl
5241 #undef TARGET_EXPAND_BUILTIN
5242 #define TARGET_EXPAND_BUILTIN nds32_expand_builtin
5245 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
5246 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P nds32_use_blocks_for_constant_p
5249 /* ------------------------------------------------------------------------ */
5251 /* Initialize the GCC target structure. */
5253 struct gcc_target targetm
= TARGET_INITIALIZER
;
5255 /* ------------------------------------------------------------------------ */