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.