On Sun, Jul 30, 2017 at 10:14 PM, Uros Bizjak <ubiz...@gmail.com> wrote: > Hello! > > attribute ((naked)) generates function body without function frame, > and as shown in PR 25967 [1], users are looking for this feature also > for x86 targets. Recently, Daniel introduced a testcase that would > benefit from this attribute.
Following additional patch enables passing arguments to a naked function. Testcases gcc.target/i386/naked-3.c and gcc.target/i386/naked-4.c show necessary decorations (i.e. mregparm for -m32 and volatile "ret" for function result) to reliably pass function arguments to and function result from naked functions. 2017-07-31 Uros Bizjak <ubiz...@gmail.com> PR target/25967 * config/i386/i386.c (ix86_allocate_stack_slots_for_args): New function. (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define. testsuite/ChangeLog: 2017-07-31 Uros Bizjak <ubiz...@gmail.com> PR target/25967 * gcc.target/i386/naked-3.c (dg-options): Use -O0. (naked): Add attribute regparm(1) for x86_32 targets. Add integer argument. Remove global "data" variable. (main): Pass integer argument to naked function. * gcc.target/i386/naked-4.c: New test. Bootstrapped and regression tested on x86_64-linux-gnu {-m32}. Committed to mainline SVN. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 250736) +++ config/i386/i386.c (working copy) @@ -31676,6 +31676,13 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rt } static bool +ix86_allocate_stack_slots_for_args (void) +{ + /* Naked functions should not allocate stack slots for arguments. */ + return !ix86_function_naked (current_function_decl); +} + +static bool ix86_warn_func_return (tree decl) { /* Naked functions are implemented entirely in assembly, including the @@ -52727,6 +52734,8 @@ ix86_run_selftests (void) #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack +#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS +#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args #undef TARGET_FUNCTION_ARG_ADVANCE #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance #undef TARGET_FUNCTION_ARG Index: testsuite/gcc.target/i386/naked-3.c =================================================================== --- testsuite/gcc.target/i386/naked-3.c (revision 250736) +++ testsuite/gcc.target/i386/naked-3.c (working copy) @@ -1,17 +1,18 @@ /* { dg-do run { target *-*-linux* *-*-gnu* } } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O0" } */ #include <unistd.h> #include <signal.h> #include <stdlib.h> -int data; - /* Verify that naked function traps at the end. */ void __attribute__((naked, noinline, noclone)) -naked (void) +#ifdef __i386__ +__attribute__((regparm(1))) +#endif +naked (int data) { if (data == 0x12345678) return; @@ -32,8 +33,7 @@ int main () s.sa_flags = 0; sigaction (SIGILL, &s, NULL); - data = 0x12345678; - naked (); + naked (0x12345678); abort (); } Index: testsuite/gcc.target/i386/naked-4.c =================================================================== --- testsuite/gcc.target/i386/naked-4.c (nonexistent) +++ testsuite/gcc.target/i386/naked-4.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O0" } */ +/* { dg-additional-options "-mregparm=3" { target ia32 } } */ + +/* Verify that __attribute__((naked)) produces a naked function + that does not allocate stack slots for args. */ +extern void bar (int); + +int +__attribute__((naked)) +foo (int a, int b, int c) +{ + bar (c); + asm volatile ("ret" :: "a" (b)); +} + +/* { dg-final { scan-assembler-not "%\[re\]bp" } } */