comparison gcc/config/fr30/fr30.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* FR30 specific functions. 1 /* FR30 specific functions.
2 Copyright (C) 1998-2018 Free Software Foundation, Inc. 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions. 3 Contributed by Cygnus Solutions.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify 7 GCC is free software; you can redistribute it and/or modify
37 #include "stor-layout.h" 37 #include "stor-layout.h"
38 #include "varasm.h" 38 #include "varasm.h"
39 #include "output.h" 39 #include "output.h"
40 #include "expr.h" 40 #include "expr.h"
41 #include "builtins.h" 41 #include "builtins.h"
42 #include "calls.h"
42 43
43 /* This file should be included last. */ 44 /* This file should be included last. */
44 #include "target-def.h" 45 #include "target-def.h"
45 46
46 /*}}}*/ 47 /*}}}*/
110 static struct fr30_frame_info current_frame_info; 111 static struct fr30_frame_info current_frame_info;
111 112
112 /* Zero structure to initialize current_frame_info. */ 113 /* Zero structure to initialize current_frame_info. */
113 static struct fr30_frame_info zero_frame_info; 114 static struct fr30_frame_info zero_frame_info;
114 115
115 static void fr30_setup_incoming_varargs (cumulative_args_t, machine_mode, 116 static void fr30_setup_incoming_varargs (cumulative_args_t,
116 tree, int *, int); 117 const function_arg_info &,
117 static bool fr30_must_pass_in_stack (machine_mode, const_tree); 118 int *, int);
118 static int fr30_arg_partial_bytes (cumulative_args_t, machine_mode, 119 static bool fr30_must_pass_in_stack (const function_arg_info &);
119 tree, bool); 120 static int fr30_arg_partial_bytes (cumulative_args_t,
120 static rtx fr30_function_arg (cumulative_args_t, machine_mode, 121 const function_arg_info &);
121 const_tree, bool); 122 static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &);
122 static void fr30_function_arg_advance (cumulative_args_t, machine_mode, 123 static void fr30_function_arg_advance (cumulative_args_t,
123 const_tree, bool); 124 const function_arg_info &);
124 static bool fr30_frame_pointer_required (void); 125 static bool fr30_frame_pointer_required (void);
125 static rtx fr30_function_value (const_tree, const_tree, bool); 126 static rtx fr30_function_value (const_tree, const_tree, bool);
126 static rtx fr30_libcall_value (machine_mode, const_rtx); 127 static rtx fr30_libcall_value (machine_mode, const_rtx);
127 static bool fr30_function_value_regno_p (const unsigned int); 128 static bool fr30_function_value_regno_p (const unsigned int);
128 static bool fr30_can_eliminate (const int, const int); 129 static bool fr30_can_eliminate (const int, const int);
129 static void fr30_asm_trampoline_template (FILE *); 130 static void fr30_asm_trampoline_template (FILE *);
130 static void fr30_trampoline_init (rtx, tree, rtx); 131 static void fr30_trampoline_init (rtx, tree, rtx);
131 static int fr30_num_arg_regs (machine_mode, const_tree); 132 static int fr30_num_arg_regs (const function_arg_info &);
132 133
133 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM)) 134 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
134 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM)) 135 #define RETURN_POINTER_MASK (1 << (RETURN_POINTER_REGNUM))
135 136
136 /* Tell prologue and epilogue if register REGNO should be saved / restored. 137 /* Tell prologue and epilogue if register REGNO should be saved / restored.
138 Don't consider them here. */ 139 Don't consider them here. */
139 #define MUST_SAVE_REGISTER(regno) \ 140 #define MUST_SAVE_REGISTER(regno) \
140 ( (regno) != RETURN_POINTER_REGNUM \ 141 ( (regno) != RETURN_POINTER_REGNUM \
141 && (regno) != FRAME_POINTER_REGNUM \ 142 && (regno) != FRAME_POINTER_REGNUM \
142 && df_regs_ever_live_p (regno) \ 143 && df_regs_ever_live_p (regno) \
143 && ! call_used_regs [regno] ) 144 && ! call_used_or_fixed_reg_p (regno))
144 145
145 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed) 146 #define MUST_SAVE_FRAME_POINTER (df_regs_ever_live_p (FRAME_POINTER_REGNUM) || frame_pointer_needed)
146 #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile) 147 #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile)
147 148
148 #if UNITS_PER_WORD == 4 149 #if UNITS_PER_WORD == 4
456 /* Do any needed setup for a variadic function. We must create a register 457 /* Do any needed setup for a variadic function. We must create a register
457 parameter block, and then copy any anonymous arguments, plus the last 458 parameter block, and then copy any anonymous arguments, plus the last
458 named argument, from registers into memory. * copying actually done in 459 named argument, from registers into memory. * copying actually done in
459 fr30_expand_prologue(). 460 fr30_expand_prologue().
460 461
461 ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument 462 CUM has not been updated for the last named argument which has type TYPE
462 which has type TYPE and mode MODE, and we rely on this fact. */ 463 and mode MODE, and we rely on this fact. */
463 void 464 void
464 fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v, 465 fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v,
465 machine_mode mode, 466 const function_arg_info &arg,
466 tree type ATTRIBUTE_UNUSED,
467 int *pretend_size, 467 int *pretend_size,
468 int second_time ATTRIBUTE_UNUSED) 468 int second_time ATTRIBUTE_UNUSED)
469 { 469 {
470 CUMULATIVE_ARGS *arg_regs_used_so_far 470 CUMULATIVE_ARGS *arg_regs_used_so_far
471 = get_cumulative_args (arg_regs_used_so_far_v); 471 = get_cumulative_args (arg_regs_used_so_far_v);
472 int size; 472 int size;
473 473
474 /* All BLKmode values are passed by reference. */ 474 /* All BLKmode values are passed by reference. */
475 gcc_assert (mode != BLKmode); 475 gcc_assert (arg.mode != BLKmode);
476 476
477 /* ??? This run-time test as well as the code inside the if 477 /* ??? This run-time test as well as the code inside the if
478 statement is probably unnecessary. */ 478 statement is probably unnecessary. */
479 if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v)) 479 if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v))
480 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named 480 /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
481 arg must not be treated as an anonymous arg. */ 481 arg must not be treated as an anonymous arg. */
482 /* ??? This is a pointer increment, which makes no sense. */ 482 /* ??? This is a pointer increment, which makes no sense. */
483 arg_regs_used_so_far += fr30_num_arg_regs (mode, type); 483 arg_regs_used_so_far += fr30_num_arg_regs (arg);
484 484
485 size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far); 485 size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
486 486
487 if (size <= 0) 487 if (size <= 0)
488 return; 488 return;
741 741
742 /* Return true if we should pass an argument on the stack rather than 742 /* Return true if we should pass an argument on the stack rather than
743 in registers. */ 743 in registers. */
744 744
745 static bool 745 static bool
746 fr30_must_pass_in_stack (machine_mode mode, const_tree type) 746 fr30_must_pass_in_stack (const function_arg_info &arg)
747 { 747 {
748 if (mode == BLKmode) 748 return arg.mode == BLKmode || arg.aggregate_type_p ();
749 return true; 749 }
750 if (type == NULL) 750
751 return false; 751 /* Compute the number of word sized registers needed to hold function
752 return AGGREGATE_TYPE_P (type); 752 argument ARG. */
753 }
754
755 /* Compute the number of word sized registers needed to hold a
756 function argument of mode INT_MODE and tree type TYPE. */
757 static int 753 static int
758 fr30_num_arg_regs (machine_mode mode, const_tree type) 754 fr30_num_arg_regs (const function_arg_info &arg)
759 { 755 {
760 int size; 756 if (targetm.calls.must_pass_in_stack (arg))
761
762 if (targetm.calls.must_pass_in_stack (mode, type))
763 return 0; 757 return 0;
764 758
765 if (type && mode == BLKmode) 759 int size = arg.promoted_size_in_bytes ();
766 size = int_size_in_bytes (type);
767 else
768 size = GET_MODE_SIZE (mode);
769
770 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; 760 return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
771 } 761 }
772 762
773 /* Returns the number of bytes in which *part* of a parameter of machine 763 /* Returns the number of bytes of argument registers required to hold *part*
774 mode MODE and tree type TYPE (which may be NULL if the type is not known). 764 of argument ARG. If the argument fits entirely in the argument registers,
775 If the argument fits entirely in the argument registers, or entirely on 765 or entirely on the stack, then 0 is returned. CUM is the number of
776 the stack, then 0 is returned. 766 argument registers already used by earlier parameters to the function. */
777 CUM is the number of argument registers already used by earlier
778 parameters to the function. */
779 767
780 static int 768 static int
781 fr30_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode, 769 fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
782 tree type, bool named)
783 { 770 {
784 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 771 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
785 772
786 /* Unnamed arguments, i.e. those that are prototyped as ... 773 /* Unnamed arguments, i.e. those that are prototyped as ...
787 are always passed on the stack. 774 are always passed on the stack.
788 Also check here to see if all the argument registers are full. */ 775 Also check here to see if all the argument registers are full. */
789 if (named == 0 || *cum >= FR30_NUM_ARG_REGS) 776 if (!arg.named || *cum >= FR30_NUM_ARG_REGS)
790 return 0; 777 return 0;
791 778
792 /* Work out how many argument registers would be needed if this 779 /* Work out how many argument registers would be needed if this
793 parameter were to be passed entirely in registers. If there 780 parameter were to be passed entirely in registers. If there
794 are sufficient argument registers available (or if no registers 781 are sufficient argument registers available (or if no registers
795 are needed because the parameter must be passed on the stack) 782 are needed because the parameter must be passed on the stack)
796 then return zero, as this parameter does not require partial 783 then return zero, as this parameter does not require partial
797 register, partial stack stack space. */ 784 register, partial stack stack space. */
798 if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS) 785 if (*cum + fr30_num_arg_regs (arg) <= FR30_NUM_ARG_REGS)
799 return 0; 786 return 0;
800 787
801 return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD; 788 return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
802 } 789 }
803 790
804 static rtx 791 static rtx
805 fr30_function_arg (cumulative_args_t cum_v, machine_mode mode, 792 fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
806 const_tree type, bool named)
807 { 793 {
808 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 794 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
809 795
810 if (!named 796 if (!arg.named
811 || fr30_must_pass_in_stack (mode, type) 797 || fr30_must_pass_in_stack (arg)
812 || *cum >= FR30_NUM_ARG_REGS) 798 || *cum >= FR30_NUM_ARG_REGS)
813 return NULL_RTX; 799 return NULL_RTX;
814 else 800 else
815 return gen_rtx_REG (mode, *cum + FIRST_ARG_REGNUM); 801 return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM);
816 } 802 }
817 803
818 /* A C statement (sans semicolon) to update the summarizer variable CUM to 804 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
819 advance past an argument in the argument list. The values MODE, TYPE and
820 NAMED describe that argument. Once this is done, the variable CUM is
821 suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
822
823 This macro need not do anything if the argument in question was passed on
824 the stack. The compiler knows how to track the amount of stack space used
825 for arguments without any special help. */
826 static void 805 static void
827 fr30_function_arg_advance (cumulative_args_t cum, machine_mode mode, 806 fr30_function_arg_advance (cumulative_args_t cum,
828 const_tree type, bool named) 807 const function_arg_info &arg)
829 { 808 {
830 *get_cumulative_args (cum) += named * fr30_num_arg_regs (mode, type); 809 if (arg.named)
810 *get_cumulative_args (cum) += fr30_num_arg_regs (arg);
831 } 811 }
832 812
833 /*}}}*/ 813 /*}}}*/
834 /*{{{ Operand predicates */ 814 /*{{{ Operand predicates */
835 815