This is the mail archive of the gcc@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]
Other format: [Raw text]

Re: ARM inline assembly usage in Linux kernel


Andrew Pinski <pinskia@gmail.com> writes:
> On Tue, Feb 18, 2014 at 6:56 PM, Saleem Abdulrasool
> <compnerd@compnerd.org> wrote:
>> Hello.
>>
>> I am sending this at the behest of Renato.  I have been working on the ARM
>> integrated assembler in LLVM and came across an interesting item in the Linux
>> kernel.
>>
>> I am wondering if this is an unstated covenant between the kernel and GCC or
>> simply a clever use of an unintended/undefined behaviour.
>>
>> The Linux kernel uses the *compiler* as a fancy preprocessor to generate a
>> specially crafted assembly file.  This file is then post-processed via sed to
>> generate a header containing constants which is shared across assembly and C
>> sources.
>>
>> In order to clarify the question, I am selecting a particular example and
>> pulling out the relevant bits of the source code below.
>>
>> #define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
>>
>> #define __NR_PAGEFLAGS 22
>>
>> void definitions(void) {
>>   DEFINE(NR_PAGEFLAGS, __NR_PAGEFLAGS);
>> }
>>
>> This is then assembled to generate the following:
>>
>> ->NR_PAGEFLAGS #22 __NR_PAGEFLAGS
>>
>> This will later be post-processed to generate:
>>
>> #define NR_PAGELAGS 22 /* __NR_PAGEFLAGS */
>>
>> By using the inline assembler to evaluate (constant) expressions into constant
>> values and then emit that using a special identifier (->) is a fairly clever
>> trick.  This leads to my question: is this just use of an unintentional
>> "feature" or something that was worked out between the two projects.

If the output is being post-processed by sed then maybe you could put
a comment character at the beginning of the line and sed it out?
But I tend to agree with Andrew that for -S output the compiler should
be prepared to accept asm strings that it can't parse, even if the integrated
assembler thinks it understands every instruction.

> I don't see why this is a bad use of the inline-asm.  GCC does not
> know and is not supposed to know what the string inside the inline-asm
> is going to be.  In fact if you have a newer assembler than the
> compiler, you could use instructions that GCC does not even know
> about.

Yeah, FWIW, I agree this is a valid use of inline asm.  The use of volatile
in a reachable part of definitions() means that the asm (and thus the
asm string) must be kept if definitions() is kept.

I doubt the idea was agreed with GCC developers because no GCC changes were
needed to use inline asm this way.

> This is the purpose of inline-asm.  I think it was a bad
> design decision on LLVM/clang's part that it would check the assembly
> code up front.

Being able to parse it is a useful feature.  E.g. it means you can get an
accurate byte length for the asm, which is something that we otherwise
have to guess by multiplying the number of lines by a constant factor.
(And that's wrong for MIPS assembly macros, unless you use a very
conservative constant factor.)

I agree that having an unrecognised asm shouldn't be a hard error until
assembly time though.  Saleem, is the problem that this is being rejected
earlier?

Thanks,
Richard


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