Hi! On Thu, Apr 30, 2020 at 02:48:18PM +0200, FRÉDÉRIC RECOULES wrote: > I am looking for some clarification about how are working the memory > operands, especially when the constraint allows memory only (eg. "m"). > Please note that in a lesser extent, I know (by looking the gcc sources) how > the things are currently working but I wonder if it is a design choice or > simply a serendipitous engineering consequence. > Indeed, as far as I know, the documentation is not explicit on this. > > Only things related to memory I have found are: > > A string constant specifying constraints on the placement of the operand; > > See Constraints, for details. > > ‘ m ’ A memory operand is allowed, with any kind of address that the > > machine supports in general. > > When I read this, I think that "m" work exactly as "r" from a C point of > view. But in fact, there are some conceptual corner cases where there are not > equivalent. > > (1) It is said that an output must be an lvalue. However, it is said nowhere > (except that compilation fails) that if the constraint allows only memory, an > input expression must be an lvalue too.
But it has to. *Anything* in memory, inline asm or not, can have its address taken. "Anything in memory is an lvalue". > There are a lot of workarounds, but why the following code (actually not > relevant) is rejected? > __asm__ ("movl %1, %0" : "=r" (x) : "m" (1)); > I would think that the compiler could put the constant 1 in the stack or in > a static address or even reuse any memory address known to hold the value 1. It could, but it doesn't. GCC requires memory constraints to refer to something that can have its address taken. Constants do not have an address. You can put the constant in a variable yourself. > (2) If the constraint allows only memory, does the compiler allowed to make a > copy? (if no, why?) A memory constraint refers to *that* memory. Copies would not work in general, considering atomics and the like. > (2.1) Thus, if I declare an output and an input using the same lvalue, am I > guaranteed that they both point to the same location? (as far as I know, it > is not true for register constraint) > __asm__ ("incl %0" : "=m" (x) : "m" (x)); This is correct. Registers should use "0" etc. Memory is like you say. > (2.2) Moreover, in the following example of the doc, is edi guaranteed to > point to the memory pointed by "m" (*(const char (*)[]) p) ? > > > asm("repne scasb" > > : "=c" (count), "+D" (p) > > : "m" (*(const char (*)[]) p), "0" (-1), "a" (0)); Why not? They are just two independent inputs? That one is the address of the other doesn't really change anything?