On 05/09/16 15:46, Bernd Schmidt wrote: > On 05/09/2016 03:37 PM, Bernd Edlinger wrote: >> On 05/09/16 09:56, Richard Biener wrote: >>> >>> At least it sounds to me that its semantics can be fully expressed >>> with generic asms? (Maybe apart from the only-if-ASM_STRING-is-empty >>> part) >>> >> >> That was also my first idea too. >> >> In simple cases an asm ("whatever"); should do the same as >> asm ("whatever" ::: ); >> >> Adding a "memory" to the clobber list would be simple that's true. >> >> But in general it can be pretty complicated, especially if the >> string contains the special characters % { | }. > > Is the only difference in how the string is output? Maybe we can have a > slightly different form of ASM_OPERANDS (with a bit set, or with the > string wrapped in something else) to indicate that it's old-style.
Most of the difference is what happens in final.c, and adding a new attribute to the ASM_OPERANDS tree node is definitely one option. I tried to implement it in a way that causes the least confusion. There are lots of different tree representations for an extended asm statement in genereal, but only one for a basic asm. An extended asm that has no outputs and no clobbers, is an ASM_OPERAND node with optional vector of ASM_INPUTs containig the input constraint: ASM_OPERAND { "asm", "", 0, VEC { inputs...}, VEC { ASM_INPUT ("x")...} but if it has any CLOBBERS, it will look like this: PARALLEL { ASM_OPERAND, CLOBBER... } if it has one output, and zero clobbers we have: SET { x, ASM_OPERAND } and in case we have more than one output we have: PARALLEL { SET { x, ASM_OPERAND }... , CLOBBER... } A basic asm is just an ASM_INPUT that is not underneath an ASM_OPERAND. But to add any CLOBBERs to this ASM_INPUT it has to be in PARALLEL with the CLOBBERs, so that would look like this: PARALLEL { ASM_INPUT{ "asm" }, CLOBBER... } There are lots of places where we need to know if a statement is an assembler statement, in most places this is done in this way: GET_CODE (PATTERN (insn)) == ASM_INPUT || asm_noperands (PATTERN (insn)) >= 0 There are a handful of places where it is done it this way: GET_CODE (PATTERN (insn)) == ASM_INPUT || extract_asm_operands (PATTERN (insn)) != NULL_RTX extract_asm_operands locates the ASM_OPERAND node from an extended asm that can have either of the several forms above, but in most cases the result is not looked at. Making extract_asm_operands return anything but an ASM_OPERANDS is impossible, but making asm_noperands return 0 for a PARALLEL { ASM_INPUT, CLOBBER... } is not too complicated. Fortunately, all the remaining uses of extract_asm_operands really mean an extended asm. Hope that explains my idea. Thanks Bernd.