Re: asm volatile statement reordering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 17/10/17 10:55, Jeffrey Walton wrote:
> On Tue, Oct 17, 2017 at 4:12 AM, Andrew Haley <aph@xxxxxxxxxx> wrote:
>> On 17/10/17 09:01, Jeffrey Walton wrote:
>>> On Tue, Oct 17, 2017 at 3:58 AM, Andrew Haley <aph@xxxxxxxxxx> wrote:
>>>> On 17/10/17 08:32, Jeffrey Walton wrote:
>>>>> GCC guesses wrong on occasion. It will remove code that has value that
>>>>> but does not produce an output because the language does not allow us
>>>>> to express it.
>>>>>
>>>>> The C language lacks what we need to express what we need to do. Its a
>>>>> failure of the C (and C++) committees. Its not a GCC failure.
>>>>
>>>> I disagree.  If you want a bunch of asms to execute in a particular
>>>> order, add a memory clobber or some dependencies.  It's not difficult
>>>> once you have the understanding.  In this particular case, fixing it
>>>> is trivial, and there are many ways to do it.
>>>
>>> Forgive my ignorance... How does one do it without ASM and in a
>>> cross-platform fashion?
>>
>> I don't understand what you are asking.
> 
> Sorry about that Andrew. I had two or three other use cases in mind
> when I wrote that. The use case offered by Brown requires it.
> 
> Sorry again.
> 
> Jeff
> 

I don't what use-cases you have in mind here, but there are a few things
you can do with asm that /are/ cross-platform:

A basic memory barrier:

	asm volatile("" ::: "memory")

Telling the compiler that it has to have evaluated "x" at this point:

#define forceDependency(x) \
                asm volatile("" :: "" (x) : )

Telling the compiler that it has to have evaluated "x" at this point,
but that "x" might change here so it can't use that knowledge for
optimisation:

#define forgetCompilerKnowledge(x) \
                asm ("" : "+g" (x))

That one is a bit like telling the compiler to treat the previous write
to "x" as a volatile write, and the next read like a volatile read,
except the compiler can keep x in a register all the time.

This macro does the same, but covers a block of memory:

#define forgetCompilerBlock(start, size) \
    do { typedef struct { char x[size]; } XS; XS *p = (XS *) start; \
      asm ("" : "+m" (*p)); \
    } while (0);


Lots can be done cross-platform in inline asm when the actual assembly
part is empty!





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux