This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] __attribute__((naked))
- To: egcs-patches at egcs dot cygnus dot com
- Subject: [PATCH] __attribute__((naked))
- From: Bill Currie <bcurrie at tssc dot co dot nz>
- Date: Thu, 03 Jun 1999 11:03:48 +1200
- Organization: NZ Telecommincations Systems Support Center
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.