From: Chung-Ju Wu Date: Sun, 27 May 2018 06:46:43 +0000 (+0000) Subject: [NDS32] new attribute no_prologue and new option -mret-in-naked-func. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=54c537e66c26882d8b3202a3e72a6fb9464d9969;p=gcc.git [NDS32] new attribute no_prologue and new option -mret-in-naked-func. gcc/ * config/nds32/nds32.c (nds32_attribute_table): Add "no_prologue". (nds32_init_machine_status): Initialize machine->attr_naked_p and machine->attr_no_prologue_p. (nds32_compute_stack_frame): Check "naked" and "no_prologue" attributes. (nds32_naked_function_p): Handle "naked" and "no_prologue" attributes. (nds32_expand_epilogue): Consider attr_naked_p. (nds32_expand_epilogue_v3pop): Likewise. (nds32_can_use_return_insn): Likewise. * config/nds32/nds32.h (machine_function): Add attr_naked_p and attr_no_prologue_p fields. * config/nds32/nds32.opt (mret-in-naked-func): New option. From-SVN: r260803 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d16ca7108c..73c578165f3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-05-27 Chung-Ju Wu + + * config/nds32/nds32.c (nds32_attribute_table): Add "no_prologue". + (nds32_init_machine_status): Initialize machine->attr_naked_p and + machine->attr_no_prologue_p. + (nds32_compute_stack_frame): Check "naked" and "no_prologue" attributes. + (nds32_naked_function_p): Handle "naked" and "no_prologue" attributes. + (nds32_expand_epilogue): Consider attr_naked_p. + (nds32_expand_epilogue_v3pop): Likewise. + (nds32_can_use_return_insn): Likewise. + * config/nds32/nds32.h (machine_function): Add attr_naked_p and + attr_no_prologue_p fields. + * config/nds32/nds32.opt (mret-in-naked-func): New option. + 2018-05-27 Jakub Jelinek PR target/85918 diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c index 649e6f4b4db..9fcd24f7e34 100644 --- a/gcc/config/nds32/nds32.c +++ b/gcc/config/nds32/nds32.c @@ -320,6 +320,10 @@ static const struct attribute_spec nds32_attribute_table[] = /* The attribute is used to tell this function to be ROM patch. */ { "indirect_call",0, 0, false, false, false, false, NULL, NULL }, + /* FOR BACKWARD COMPATIBILITY, + this attribute also tells no prologue/epilogue. */ + { "no_prologue", 0, 0, false, false, false, false, NULL, NULL }, + /* The last attribute spec is set to be NULL. */ { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -348,6 +352,10 @@ nds32_init_machine_status (void) /* Initially this function is not under strictly aligned situation. */ machine->strict_aligned_p = 0; + /* Initially this function has no naked and no_prologue attributes. */ + machine->attr_naked_p = 0; + machine->attr_no_prologue_p = 0; + return machine; } @@ -365,6 +373,15 @@ nds32_compute_stack_frame (void) needs prologue/epilogue. */ cfun->machine->naked_p = 0; + /* We need to mark whether this function has naked and no_prologue + attribute so that we can distinguish the difference if users applies + -mret-in-naked-func option. */ + cfun->machine->attr_naked_p + = lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) + ? 1 : 0; + cfun->machine->attr_no_prologue_p + = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) + ? 1 : 0; /* If __builtin_eh_return is used, we better have frame pointer needed so that we can easily locate the stack slot of return address. */ @@ -501,7 +518,7 @@ nds32_compute_stack_frame (void) } /* Check if this function can omit prologue/epilogue code fragment. - If there is 'naked' attribute in this function, + If there is 'no_prologue'/'naked' attribute in this function, we can set 'naked_p' flag to indicate that we do not have to generate prologue/epilogue. Or, if all the following conditions succeed, @@ -514,7 +531,8 @@ nds32_compute_stack_frame (void) is no outgoing size. condition 3: There is no local_size, which means we do not need to adjust $sp. */ - if (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) + if (lookup_attribute ("no_prologue", DECL_ATTRIBUTES (current_function_decl)) + || lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) || (cfun->machine->callee_saved_first_gpr_regno == SP_REGNUM && cfun->machine->callee_saved_last_gpr_regno == SP_REGNUM && cfun->machine->callee_saved_first_fpr_regno == SP_REGNUM @@ -1376,14 +1394,22 @@ nds32_needs_double_word_align (machine_mode mode, const_tree type) static bool nds32_naked_function_p (tree func) { - tree t; + /* FOR BACKWARD COMPATIBILITY, + we need to support 'no_prologue' attribute as well. */ + tree t_naked; + tree t_no_prologue; if (TREE_CODE (func) != FUNCTION_DECL) abort (); - t = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); + /* We have to use lookup_attribute() to check attributes. + Because attr_naked_p and attr_no_prologue_p are set in + nds32_compute_stack_frame() and the function has not been + invoked yet. */ + t_naked = lookup_attribute ("naked", DECL_ATTRIBUTES (func)); + t_no_prologue = lookup_attribute ("no_prologue", DECL_ATTRIBUTES (func)); - return (t != NULL_TREE); + return ((t_naked != NULL_TREE) || (t_no_prologue != NULL_TREE)); } /* Function that determine whether a load postincrement is a good thing to use @@ -4719,7 +4745,16 @@ nds32_expand_epilogue (bool sibcall_p) /* Generate return instruction by using 'return_internal' pattern. Make sure this instruction is after gen_blockage(). */ if (!sibcall_p) - emit_jump_insn (gen_return_internal ()); + { + /* We need to further check attributes to determine whether + there should be return instruction at epilogue. + If the attribute naked exists but -mno-ret-in-naked-func + is issued, there is NO need to generate return instruction. */ + if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) + return; + + emit_jump_insn (gen_return_internal ()); + } return; } @@ -5075,9 +5110,19 @@ nds32_expand_epilogue_v3pop (bool sibcall_p) if (cfun->machine->naked_p) { /* Generate return instruction by using 'return_internal' pattern. - Make sure this instruction is after gen_blockage(). */ + Make sure this instruction is after gen_blockage(). + First we need to check this is a function without sibling call. */ if (!sibcall_p) - emit_jump_insn (gen_return_internal ()); + { + /* We need to further check attributes to determine whether + there should be return instruction at epilogue. + If the attribute naked exists but -mno-ret-in-naked-func + is issued, there is NO need to generate return instruction. */ + if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) + return; + + emit_jump_insn (gen_return_internal ()); + } return; } @@ -5241,6 +5286,11 @@ nds32_can_use_return_insn (void) if (!reload_completed) return 0; + /* If attribute 'naked' appears but -mno-ret-in-naked-func is used, + we cannot use return instruction. */ + if (cfun->machine->attr_naked_p && !flag_ret_in_naked_func) + return 0; + sp_adjust = cfun->machine->local_size + cfun->machine->out_args_size + cfun->machine->callee_saved_area_gpr_padding_bytes diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index e00622b58be..523492fea17 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -318,6 +318,10 @@ struct GTY(()) machine_function 2. The rtl lowering and optimization are close to target code. For this case we need address to be strictly aligned. */ int strict_aligned_p; + + /* Record two similar attributes status. */ + int attr_naked_p; + int attr_no_prologue_p; }; /* A C structure that contains the arguments information. */ diff --git a/gcc/config/nds32/nds32.opt b/gcc/config/nds32/nds32.opt index a9cd72c422b..d32e2ec1165 100644 --- a/gcc/config/nds32/nds32.opt +++ b/gcc/config/nds32/nds32.opt @@ -439,6 +439,10 @@ mforce-no-ext-dsp Target Undocumented Report Mask(FORCE_NO_EXT_DSP) Force disable hardware loop, even use -mext-dsp. +mret-in-naked-func +Target Var(flag_ret_in_naked_func) Init(1) +Generate return instruction in naked function. + malways-save-lp Target Var(flag_always_save_lp) Init(0) Always save $lp in the stack.