On 08/28/2017 11:56 AM, Michael Matz wrote: > 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: Hmm, maybe I've spent too much time with .md files rather than looking at how folks are using asms through the years.
> > 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) How do we represent the y+z case in particular. Isn't that shoved into a gimple temporary and ultimately a pseudo? > > 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 I'm surprised this actually works, but again, it may be because I don't write a lot of asms and my md-fu isn't what it used to be. > >> 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. I'll trust you on this -- I haven't gone in and looked at the code. > >> 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. True. I'm not thinking in terms of lvalues and rvalues, but in terms of allocnos and pseudos that the allocators and reloaders operate on. > >>> 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'. Ack. Hmm, yea, I misunderstood part of this. Hmm.... Going back to pshortis issue, it's interesting how the size of the input operand is being used to determine the mode of the matching output operand. That ought to be not-too-difficult to find within GCC... With any luck there'd be a useful comment in that code. jeff Jeff