input and output one. With this modifier you will have the correct
values on all possible paths from the @code{asm goto}.
-To reference a label in the assembler template,
-prefix it with @samp{%l} (lowercase @samp{L}) followed
-by its (zero-based) position in @var{GotoLabels} plus the number of input
-operands. For example, if the @code{asm} has three inputs and references two
-labels, refer to the first label as @samp{%l3} and the second as @samp{%l4}).
-
-Alternately, you can reference labels using the actual C label name enclosed
-in brackets. For example, to reference a label named @code{carry}, you can
-use @samp{%l[carry]}. The label must still be listed in the @var{GotoLabels}
-section when using this approach.
+To reference a label in the assembler template, prefix it with
+@samp{%l} (lowercase @samp{L}) followed by its (zero-based) position
+in @var{GotoLabels} plus the number of input and output operands.
+Output operand with constraint modifier @samp{+} is counted as two
+operands because it is considered as one output and one input operand.
+For example, if the @code{asm} has three inputs, one output operand
+with constraint modifier @samp{+} and one output operand with
+constraint modifier @samp{=} and references two labels, refer to the
+first label as @samp{%l6} and the second as @samp{%l7}).
+
+Alternately, you can reference labels using the actual C label name
+enclosed in brackets. For example, to reference a label named
+@code{carry}, you can use @samp{%l[carry]}. The label must still be
+listed in the @var{GotoLabels} section when using this approach. It
+is better to use the named references for labels as in this case you
+can avoid counting input and output operands and special treatment of
+output operands with constraint modifier @samp{+}.
Here is an example of @code{asm goto} for i386:
resolve_operand_name_1 (char *p, tree outputs, tree inputs, tree labels)
{
char *q;
- int op;
+ int op, op_inout;
tree t;
/* Collect the operand name. */
*q = '\0';
/* Resolve the name to a number. */
- for (op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
+ for (op_inout = op = 0, t = outputs; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (TREE_PURPOSE (t));
if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
goto found;
+ tree constraint = TREE_VALUE (TREE_PURPOSE (t));
+ if (constraint && strchr (TREE_STRING_POINTER (constraint), '+') != NULL)
+ op_inout++;
}
for (t = inputs; t ; t = TREE_CHAIN (t), op++)
{
if (name && strcmp (TREE_STRING_POINTER (name), p) == 0)
goto found;
}
+ op += op_inout;
for (t = labels; t ; t = TREE_CHAIN (t), op++)
{
tree name = TREE_PURPOSE (t);