From: Paul Brook Date: Fri, 23 May 2008 20:36:57 +0000 (+0000) Subject: extend.texi: Clarify use of __attribute__((naked)). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=007e61c28bd45792a74a66be4feae5968468befe;p=gcc.git extend.texi: Clarify use of __attribute__((naked)). gcc/ 2008-05-23 Paul Brook Carlos O'Donell * doc/extend.texi: Clarify use of __attribute__((naked)). * doc/tm.texi: Document TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. * target.h (gcc_target): Add allocate_stack_slots_for_args. * function.c (use_register_for_decl): Use targetm.calls.allocate_stack_slots_for_args. * target-def.h (TARGET_CALLS): Add TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. * config/arm/arm.c (arm_allocate_stack_slots_for_args): New function. (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define. gcc/testsuite/ 2008-05-23 Paul Brook Carlos O'Donell * gcc.target/arm/naked-1.c: New test. * gcc.target/arm/naked-2.c: New test. Co-Authored-By: Carlos O'Donell From-SVN: r135831 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 25e09df9add..c1712af05eb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2008-05-23 Paul Brook + Carlos O'Donell + + * doc/extend.texi: Clarify use of __attribute__((naked)). + * doc/tm.texi: Document TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. + * target.h (gcc_target): Add allocate_stack_slots_for_args. + * function.c (use_register_for_decl): Use + targetm.calls.allocate_stack_slots_for_args. + * target-def.h (TARGET_CALLS): Add + TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS. + * config/arm/arm.c (arm_allocate_stack_slots_for_args): + New function. + (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define. + 2008-05-23 Eric Botcazou * expr.c (highest_pow2_factor) : New case. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 1c7002b8be4..38d4a2d9d9f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -189,6 +189,7 @@ static bool arm_cannot_copy_insn_p (rtx); static bool arm_tls_symbol_p (rtx x); static int arm_issue_rate (void); static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; +static bool arm_allocate_stack_slots_for_args (void); /* Initialize the GCC target structure. */ @@ -289,6 +290,9 @@ static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; #undef TARGET_SETUP_INCOMING_VARARGS #define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs +#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS +#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arm_allocate_stack_slots_for_args + #undef TARGET_DEFAULT_SHORT_ENUMS #define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums @@ -1619,6 +1623,14 @@ arm_current_func_type (void) return cfun->machine->func_type; } + +bool +arm_allocate_stack_slots_for_args (void) +{ + /* Naked functions should not allocate stack slots for arguments. */ + return !IS_NAKED (arm_current_func_type ()); +} + /* Return 1 if it is possible to return using a single instruction. If SIBLING is non-null, this is a test for a return before a sibling diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 78d581d62e6..f0e85933699 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2512,7 +2512,13 @@ defined by shared libraries. @cindex function without a prologue/epilogue code Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that the specified function does not need prologue/epilogue sequences generated by -the compiler. It is up to the programmer to provide these sequences. +the compiler. It is up to the programmer to provide these sequences. The +only statements that can be safely included in naked functions are +@code{asm} statements that do not have operands. All other statements, +including declarations of local variables, @code{if} statements, and so +forth, should be avoided. Naked functions should be used to implement the +body of an assembly function, while allowing the compiler to construct +the requisite function declaration for the assembler. @item near @cindex functions which do not handle memory bank switching on 68HC11/68HC12 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 12a2740173b..8c0de3b41de 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10465,3 +10465,14 @@ to the functions in @file{libgcc} that provide low-level support for call stack unwinding. It is used in declarations in @file{unwind-generic.h} and the associated definitions of those functions. @end defmac + +@deftypefn {Target Hook} {bool} TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS (void) +When optimization is disabled, this hook indicates whether or not +arguments should be allocated to stack slots. Normally, GCC allocates +stacks slots for arguments when not optimizing in order to make +debugging easier. However, when a function is declared with +@code{__attribute__((naked))}, there is no stack frame, and the compiler +cannot safely move arguments from the registers in which they are passed +to the stack. Therefore, this hook should return true in general, but +false for naked functions. The default implementation always returns true. +@end deftypefn diff --git a/gcc/function.c b/gcc/function.c index 29d4c1eda6e..5f9c3a5ce2c 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1776,6 +1776,9 @@ aggregate_value_p (const_tree exp, const_tree fntype) bool use_register_for_decl (const_tree decl) { + if (!targetm.calls.allocate_stack_slots_for_args()) + return true; + /* Honor volatile. */ if (TREE_SIDE_EFFECTS (decl)) return false; diff --git a/gcc/target-def.h b/gcc/target-def.h index c4bc6962a61..19e882f3787 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -568,6 +568,7 @@ #define TARGET_FUNCTION_VALUE default_function_value #define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer +#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS hook_bool_void_true #define TARGET_CALLS { \ TARGET_PROMOTE_FUNCTION_ARGS, \ @@ -587,7 +588,8 @@ TARGET_ARG_PARTIAL_BYTES, \ TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \ TARGET_FUNCTION_VALUE, \ - TARGET_INTERNAL_ARG_POINTER \ + TARGET_INTERNAL_ARG_POINTER, \ + TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \ } #ifndef TARGET_UNWIND_TABLES_DEFAULT diff --git a/gcc/target.h b/gcc/target.h index c331020b6ab..fa85e7cacd6 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -830,6 +830,11 @@ struct gcc_target /* Return an rtx for the argument pointer incoming to the current function. */ rtx (*internal_arg_pointer) (void); + + /* Return true if all function parameters should be spilled to the + stack. */ + bool (*allocate_stack_slots_for_args) (void); + } calls; /* Return the diagnostic message string if conversion from FROMTYPE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d18afd8e6aa..1c457cc7fa3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-05-23 Paul Brook + Carlos O'Donell + + * gcc.target/arm/naked-1.c: New test. + * gcc.target/arm/naked-2.c: New test. + 2008-05-23 Tobias Burnus PR fortran/36314 diff --git a/gcc/testsuite/gcc.target/arm/naked-1.c b/gcc/testsuite/gcc.target/arm/naked-1.c new file mode 100644 index 00000000000..8f9ff711a5e --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/naked-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* Check that function arguments aren't assigned and copied to stack slots + in naked functions. This ususally happens at -O0 (presumably for + better debugging), but is highly undesirable if we haven't created + a stack frame. */ +void __attribute__((naked)) +foo(int n) +{ + __asm__ volatile ("frob r0\n"); +} +/* { dg-final { scan-assembler "\tfrob r0" } } */ +/* { dg-final { scan-assembler-not "\tstr" } } */ diff --git a/gcc/testsuite/gcc.target/arm/naked-2.c b/gcc/testsuite/gcc.target/arm/naked-2.c new file mode 100644 index 00000000000..92e7db4447d --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/naked-2.c @@ -0,0 +1,12 @@ +/* Verify that __attribute__((naked)) produces a naked function + that does not use bx to return. Naked functions could be used + to implement interrupt routines and must not return using bx. */ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* Use more arguments than we have argument registers. */ +int __attribute__((naked)) foo(int a, int b, int c, int d, int e, int f) +{ + __asm__ volatile ("@ naked"); +} +/* { dg-final { scan-assembler "\t@ naked" } } */ +/* { dg-final { scan-assembler-not "\tbx\tlr" } } */