Hi, On Mon, 28 Aug 2017, Jeff Law wrote:
> I can't remember matching constraints ever working that way. They do work exactly so. These uses are all correct, though they place some random value into x: int x, y, z; y = z = init(); asm ("" : "=r" (x) : "r" (y+z)); asm ("" : "=r" (x) : "r" (z)); asm ("" : "=r" (x) : "r" (42)); (are we still agreeing on this? I'm having a problem understanding why you think the above wouldn't work) >From that follows that also these are correct: asm ("" : "=r" (x) : "0" (y+z)); asm ("" : "=r" (x) : "0" (z)); asm ("" : "=r" (x) : "0" (42)); It follows from the above because "0" is exactly like "r" here, except that the concrete register to use is the same as for the first operand. > REgister allocation and reloading will first try to allocate the two > objects to the same register and if that doesn't work it will emit > copies to ensure they are the same register. Not quite. Your use of "objects" muddles the issue. It doesn't allocate two objects to the same register, it allocates the two _operands_ to the same register. For output operands that's indeed an object (lvalue), for input operands it's rvalues, not objects. It does indeed allocate both to the same register, possibly using copies. If the rvalue happens to not be already in a register it makes it so by loading it into a, well, register. > But that doesn't work when one of the objects isn't a register. > There's no allocno for the constant. It's just that, a constant. Which is a perfectly fine rvalue. Input constraints never need lvalues (or objects). Maybe you're confusing this all with one particularity that _if_ the input rvalue stems from an object and that object happens to be allocated to a hardreg (via an asm("regname") declaration) then this hardreg will be used as input register? In that way some information from lvalues also flows into input operands, but it's not generally the case that they must be lvalues. > > FWIW, the above is a "portable" way to get the value 0 into 'a' without > > the compiler knowing. > ?!? Mine is just as portable and should actually work :-) Um, no? FWIW this was your example: asm ("" : "=r" (a) : "n" (0)); So, we put 0 into an immedate operand before the asm. After the asm we put some register into a. How do you suggest that the immediate asm operand (which isn't mentioned in the asm template, in fact there are no operations at all) would be placed into that output register? Answer: it isn't, the above places a random value into 'a'. Ciao, Michael.