Glad to see the push-back on this :-)

reed kotler <rkot...@mips.com> writes:
> On 05/03/2013 01:06 AM, Chung-Ju Wu wrote:
>> 2013/5/3 Chung-Ju Wu <jasonw...@gmail.com>:
>>> Or do you think 'naked' is still useful for some other cases in mips 
>>> porting?
>>> You can implement it and submit the patch to gcc-patc...@gcc.gnu.org
>>> and I believe the mips maintainers are willing to have review with you. :)
>>>
>> Oops~ I just noticed that the mips maintainer Richard Sandiford
>> already had some thought about 'naked' attribute.
>>
>> Refer to:
>> http://gcc.gnu.org/ml/gcc-patches/2008-10/msg00660.html
>>
>>
>> Best regards,
>> jasonwucj
> I think are many valid uses for the naked attribute.
>
> Here is a simple example:
>
> void foo() __attribute__((naked));
>
> void foo() {
> #ifdef DEBUG
>             C code
> #else
>             Production code in assembly
> #endif
> }
>
>
> You may have a very different implementation of several or many 
> functions when the production mode is present but for purely debugging 
> logic, some C code could be there.
I'm not convinced -- does anyone actually do this?  If so, do they do it
for performance reasons?  It would be bad if the compiler's output was
so poor that this was necessary.  Plus it prevents any kind of LTO,
which seems strange for a routine that is presumably performance-critical.
E.g. it stops the compiler from generating specialised clones, or from
inlining part of the function and leaving the rest out-of-line.

This is pedantic, but: in your example, the attribute should only be
used in the "production code" case.  So in practice the whole function
definition would be guarded by the #ifdef, with the attribute in the
production arm but not in the debug arm.  In which case why not use
a .S file?  It's surely nicer than having to write a (presumably
relatively large) asm function as a C string.

You say that naked attributes "just work".  But the problem is that
corner cases keep cropping up.  Your return question is a good example.
My understanding is that the compiler should never generate any code
itself for a naked function, and that naked functions must be an asm and
nothing else.  In particular, naked functions must not have a return statement.

It's tempting to see:

  int __attribute__((naked))
  foo (void)
  {
    asm ("....");
  }

as a normal function in which the compiler just happens not generate
any prologue and epilogue code.  But its reach is far wider than that.
See e.g.:

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53633

where the compiler must assume that the asm returns, which is something
normal asms are not allowed to do.  Another difference is that normal
asms must list the registers that they clobber (except for the usual
MIPS rule that asms can clobber $1).  E.g. for:

  int
  foo (int x)
  {
    asm ("# foo");
    return x;
  }

the compiler is free to assume that the asm clobbers neither $2 nor $4,
and so we get:

foo:
        move    $2,$4
        # foo
        j       $31

But the asm in a naked function is different, because we have to assume
that the asm can change any call-clobbered register.  This matters if
you're doing IPA to figure out which functions happen to preserve which
"call-clobbered" registers (so that callers can treat them as call-saved
instead).  Naked functions would be a special case that's easily forgotten.

Then there are questions like: what .cfi_* directives, if any, should
the compiler generate for a naked function?  Should it generate the
.cfi_startproc and .cfi_endproc, or is that the asm's job?  The answer
isn't really obvious.

That's just a list from the top of my head, I doubt it's exhaustive. :-)

Richard

Reply via email to