[NDS32] new attribute no_prologue and new option -mret-in-naked-func.
authorChung-Ju Wu <jasonwucj@gmail.com>
Sun, 27 May 2018 06:46:43 +0000 (06:46 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sun, 27 May 2018 06:46:43 +0000 (06:46 +0000)
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

gcc/ChangeLog
gcc/config/nds32/nds32.c
gcc/config/nds32/nds32.h
gcc/config/nds32/nds32.opt

index 3d16ca7108c04f0197b43e670072fd436926f78d..73c578165f37874d90130a55dbc4a7034513c06e 100644 (file)
@@ -1,3 +1,17 @@
+2018-05-27  Chung-Ju Wu  <jasonwucj@gmail.com>
+
+       * 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  <jakub@redhat.com>
 
        PR target/85918
index 649e6f4b4dbabb7e70bc4e8ce18b79b78cac81fd..9fcd24f7e34b1d93ce875d9ea24e308e7c031dbb 100644 (file)
@@ -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
index e00622b58be8a849dd872ea48b8b39dcdf1656d4..523492fea175348e76f1c24ee4e73c4eacda46fd 100644 (file)
@@ -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.  */
index a9cd72c422b8dfcd944895718c29fe19011e41e6..d32e2ec116506078e0518384a1a405d586961de8 100644 (file)
@@ -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.