This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] __attribute__((naked))


Here is the latest patch for __attribute__((naked)).  Other than the
possible additional features I mentioned on the egcs list, I consider
this to be complete.  It works as expected and the compiler would
bootstrap if I hadn't run out of disk space (I keep forgetting about
bootstrap-lean).

Thu 3 Jun 1999 10:46:30 Bill Currie (bcurrie@tssc.co.nz)
	* c-common.c: (enum attrs) add A_NAKED
	  (init_attributes) add initialization for attribute naked
	  (decl_attributes) add case for A_NAKED
	* tree.h: (struct tree_decl) add naked_function_p
	  (DECL_NAKED_FUNCTION_P) declare
	* function.c: (expand_function_end) use DECL_NAKED_FUNCTION_P
	* jump.c: include tree.h
	  (jump_optimize_1) use DECL_NAKED_FUNCTION_P
	* reorg.c: include tree.h
	  (find_end_label) use DECL_NAKED_FUNCTION_P
	* stmt.c:(expand_null_return_1) use DECL_NAKED_FUNCTION_P
	* toplev.c:(rest_of_compilation) use DECL_NAKED_FUNCTION_P

Bill
-- 
Leave others their otherness
diff -ur egcs-/gcc/c-common.c egcs/gcc/c-common.c
--- egcs-/gcc/c-common.c	Tue Apr 20 12:36:31 1999
+++ egcs/gcc/c-common.c	Mon May 31 21:44:05 1999
@@ -54,7 +54,7 @@
 enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
 	    A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
 	    A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
-	    A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
+	    A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, A_NAKED};
 
 enum format_type { printf_format_type, scanf_format_type,
 		   strftime_format_type };
@@ -394,6 +394,7 @@
   add_attribute (A_ALIAS, "alias", 1, 1, 1);
   add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1);
   add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1);
+  add_attribute (A_NAKED, "naked", 0, 0, 1);
 }
 
 /* Default implementation of valid_lang_attribute, below.  By default, there
@@ -942,6 +943,16 @@
 	    }
 	  else
 	    DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
+	  break;
+	case A_NAKED:
+	  if (TREE_CODE (decl) == FUNCTION_DECL
+	      && TREE_CODE (type) == FUNCTION_TYPE
+	      && decl_function_context (decl) == 0)
+	    {
+	      DECL_NAKED_FUNCTION_P (decl) = 1;
+	    }
+	  else
+	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
 	  break;
 	}
     }
diff -ur egcs-/gcc/function.c egcs/gcc/function.c
--- egcs-/gcc/function.c	Sat May 29 20:39:45 1999
+++ egcs/gcc/function.c	Tue Jun  1 22:52:07 1999
@@ -6608,7 +6608,7 @@
      into the epilogue.  */
 
 #ifdef HAVE_return
-  if (HAVE_return)
+  if (HAVE_return && !DECL_NAKED_FUNCTION_P (current_function_decl))
     {
       emit_jump_insn (gen_return ());
       emit_barrier ();
diff -ur egcs-/gcc/jump.c egcs/gcc/jump.c
--- egcs-/gcc/jump.c	Sat May 29 20:39:49 1999
+++ egcs/gcc/jump.c	Wed Jun  2 08:31:54 1999
@@ -54,6 +54,7 @@
 #include "config.h"
 #include "system.h"
 #include "rtl.h"
+#include "tree.h"
 #include "flags.h"
 #include "hard-reg-set.h"
 #include "regs.h"
@@ -247,7 +248,7 @@
     }
 
 #ifdef HAVE_return
-  if (HAVE_return)
+  if (HAVE_return && !DECL_NAKED_FUNCTION_P (current_function_decl))
     {
       /* If we fall through to the epilogue, see if we can insert a RETURN insn
 	 in front of it.  If the machine allows it at this point (we might be
@@ -2049,7 +2050,7 @@
   }
 
 #ifdef HAVE_return
-  if (HAVE_return)
+  if (HAVE_return && !DECL_NAKED_FUNCTION_P (current_function_decl))
     {
       /* If we fall through to the epilogue, see if we can insert a RETURN insn
 	 in front of it.  If the machine allows it at this point (we might be
diff -ur egcs-/gcc/reorg.c egcs/gcc/reorg.c
--- egcs-/gcc/reorg.c	Tue Apr 20 12:39:01 1999
+++ egcs/gcc/reorg.c	Wed Jun  2 08:31:48 1999
@@ -122,6 +122,7 @@
 #include "config.h"
 #include "system.h"
 #include "toplev.h"
+#include "tree.h"
 #include "rtl.h"
 #include "expr.h"
 #include "insn-config.h"
@@ -376,12 +377,17 @@
 #ifdef HAVE_return
       if (HAVE_return)
 	{
-	  /* The return we make may have delay slots too.  */
-	  rtx insn = gen_return ();
-	  insn = emit_jump_insn (insn);
-	  emit_barrier ();
-          if (num_delay_slots (insn) > 0)
-	    obstack_ptr_grow (&unfilled_slots_obstack, insn);
+	  if (!DECL_NAKED_FUNCTION_P (current_function_decl))
+	    {
+	      /* The return we make may have delay slots too.  */
+	      rtx insn = gen_return ();
+	      insn = emit_jump_insn (insn);
+	      emit_barrier ();
+	      if (num_delay_slots (insn) > 0)
+		obstack_ptr_grow (&unfilled_slots_obstack, insn);
+	    }
+	  else
+	    emit_barrier ();
 	}
 #endif
     }
diff -ur egcs-/gcc/stmt.c egcs/gcc/stmt.c
--- egcs-/gcc/stmt.c	Sat May 29 20:40:09 1999
+++ egcs/gcc/stmt.c	Tue Jun  1 22:42:00 1999
@@ -2619,7 +2619,8 @@
   /* Otherwise output a simple return-insn if one is available,
      unless it won't do the job.  */
 #ifdef HAVE_return
-  if (HAVE_return && use_goto == 0 && cleanup_label == 0)
+  if (HAVE_return && use_goto == 0 && cleanup_label == 0
+      && !DECL_NAKED_FUNCTION_P (current_function_decl))
     {
       emit_jump_insn (gen_return ());
       emit_barrier ();
diff -ur egcs-/gcc/toplev.c egcs/gcc/toplev.c
--- egcs-/gcc/toplev.c	Sat May 29 20:40:10 1999
+++ egcs/gcc/toplev.c	Mon May 31 22:14:38 1999
@@ -4263,7 +4263,8 @@
      it and the rest of the code and also allows delayed branch
      scheduling to operate in the epilogue.  */
 
-  thread_prologue_and_epilogue_insns (insns);
+  if (!DECL_NAKED_FUNCTION_P (decl))
+    thread_prologue_and_epilogue_insns (insns);
 
   if (flow2_dump)
     {
@@ -4390,9 +4391,11 @@
 	     fnname = XSTR (x, 0);
 
 	     assemble_start_function (decl, fnname);
-	     final_start_function (insns, asm_out_file, optimize);
+	     if (!DECL_NAKED_FUNCTION_P (decl))
+	       final_start_function (insns, asm_out_file, optimize);
 	     final (insns, asm_out_file, optimize, 0);
-	     final_end_function (insns, asm_out_file, optimize);
+	     if (!DECL_NAKED_FUNCTION_P (decl))
+	       final_end_function (insns, asm_out_file, optimize);
 	     assemble_end_function (decl, fnname);
 	     if (! quiet_flag)
 	       fflush (asm_out_file);
diff -ur egcs-/gcc/tree.h egcs/gcc/tree.h
--- egcs-/gcc/tree.h	Sat May 29 20:40:10 1999
+++ egcs/gcc/tree.h	Mon May 31 21:44:09 1999
@@ -1279,6 +1279,11 @@
    an address constant.  */
 #define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
 
+/* Used to indicate that the functions referred to by this decl will not
+   have prolog/epilog code generated.  The programmer is assumed to do
+   the right thing using (eg) asm statements.  */
+#define DECL_NAKED_FUNCTION_P(NODE) (DECL_CHECK (NODE)->decl.naked_function_p)
+
 /* Used to indicate an alias set for the memory pointed to by this
    particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
    pointer (or reference) type.  */
@@ -1333,6 +1338,7 @@
   unsigned no_instrument_function_entry_exit : 1;
   unsigned no_check_memory_usage : 1;
   unsigned comdat_flag : 1;
+  unsigned naked_function_p : 1;
 
   /* For a FUNCTION_DECL, if inline, this is the size of frame needed.
      If built-in, this is the code for which built-in function.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]