-
-/* Expand an ASM statement with operands, handling output operands
- that are not variables or INDIRECT_REFS by transforming such
- cases into cases that expand_asm_operands can handle.
-
- Arguments are same as for expand_asm_operands. */
-
-void
-c_expand_asm_operands (tree string, tree outputs, tree inputs,
- tree clobbers, int vol, location_t locus)
-{
- int noutputs = list_length (outputs);
- int i;
- /* o[I] is the place that output number I should be written. */
- tree *o = alloca (noutputs * sizeof (tree));
- tree tail;
-
- /* Record the contents of OUTPUTS before it is modified. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- {
- o[i] = TREE_VALUE (tail);
- if (o[i] == error_mark_node)
- return;
- }
-
- /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
- OUTPUTS some trees for where the values were actually stored. */
- expand_asm_operands (string, outputs, inputs, clobbers, vol, locus);
-
- /* Copy all the intermediate outputs into the specified outputs. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- {
- if (o[i] != TREE_VALUE (tail))
- {
- expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)),
- NULL_RTX, VOIDmode, EXPAND_NORMAL);
- free_temp_slots ();
-
- /* Restore the original value so that it's correct the next
- time we expand this function. */
- TREE_VALUE (tail) = o[i];
- }
- /* Detect modification of read-only values.
- (Otherwise done by build_modify_expr.) */
- else
- {
- tree type = TREE_TYPE (o[i]);
- if (TREE_READONLY (o[i])
- || TYPE_READONLY (type)
- || ((TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
- && C_TYPE_FIELDS_READONLY (type)))
- readonly_error (o[i], "modification by `asm'");
- }
- }
-
- /* Those MODIFY_EXPRs could do autoincrements. */
- emit_queue ();
-}