sunnysideup wrote:
Btw, what does this mean.. symbolic memory reference? I don't follow...
For example, a global variable can be referenced by a label, so the compiler may choose to emit that label instead of loading the address into a register.
sunnysideup wrote:
The reason that I don't want to use
Code:
asm volatile (" ": :"r"(*address));
is because sometimes I want more flexibility while choosing the
exact memory instruction. This would be really useful for stores where I can have a non-temporal (aka streaming) instruction, whereas the compiler would just have some default behaviour...
There are intrinsics for non-temporal stores, which you probably want to use if you're not hand-optimizing for one specific CPU. If you need a specific temporal load or store, you're either working with MMIO or performing some kind of magic. For MMIO, if you need to worry about the instruction then you won't be using normal pointer access anyway, so no memory clobber is necessary. Magic is outside the scope of inline assembly, so there's no guarantee it will be able to do what you want.
sunnysideup wrote:
I'm guessing that "=m"(*address) (the output constraint) is used to prevent compiler reordering since the value produced by the first asm block is used by the second asm block. (I also think that "+m"(*address) output constraint is equivalent... Am I wrong?)
With no output constraint, the value is not clobbered, so the compiler is not forced to re-read it from memory. I believe you're correct about the "+" modifier; it probably should use "+m" instead of "=m" (and wouldn't need any input operands since the output is the input).
Code:
inline void force_read(int* address)
{
asm volatile("":"+m"(*address));
asm volatile(""::"r"(*address));
}
sunnysideup wrote:
Moreover, for local variables, you'd simply get input is not directly addressable compile-time error if you'd use the & operator I believe.
I think that means you've tried to pass the address of a variable to your inline assembly without also passing the value of the variable in memory. No memory reference means the compiler doesn't need to spill it to memory, and if it doesn't get spilled it has no address.