Commit d09a75ae by Richard Kenner

(expand_asm_operands): See if output operand permits register.

(expand_asm_operands): See if output operand permits register.  If
not, mark output addressable, call expand_operand on it, and give
error if not MEM.

From-SVN: r9923
parent 621061f4
...@@ -1411,41 +1411,73 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) ...@@ -1411,41 +1411,73 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
tree type = TREE_TYPE (val); tree type = TREE_TYPE (val);
tree val1; tree val1;
int j; int j;
int found_equal; int found_equal = 0;
int allows_reg = 0;
/* If there's an erroneous arg, emit no insn. */ /* If there's an erroneous arg, emit no insn. */
if (TREE_TYPE (val) == error_mark_node) if (TREE_TYPE (val) == error_mark_node)
return; return;
/* Make sure constraint has `=' and does not have `+'. */ /* Make sure constraint has `=' and does not have `+'. Also, see
if it allows any register. Be liberal on the latter test, since
the worst that happens if we get it wrong is we issue an error
message. */
found_equal = 0; for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++) switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
{ {
if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+') case '+':
{ error ("output operand constraint contains `+'");
error ("output operand constraint contains `+'"); return;
return;
} case '=':
if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=')
found_equal = 1; found_equal = 1;
} break;
case '?': case '!': case '*': case '%': case '&':
case '0': case '1': case '2': case '3': case '4':
case 'V': case 'm': case 'o': case '<': case '>':
case 'E': case 'F': case 'G': case 'H': case 'X':
case 's': case 'i': case 'n':
case 'I': case 'J': case 'K': case 'L': case 'M':
case 'N': case 'O': case 'P': case ',':
#ifdef EXTRA_CONSTRAINT
case 'Q': case 'R': case 'S': case 'T': case 'U':
#endif
break;
case 'p': case 'g': case 'r':
default:
allows_reg = 1;
break;
}
if (! found_equal) if (! found_equal)
{ {
error ("output operand constraint lacks `='"); error ("output operand constraint lacks `='");
return; return;
} }
/* If an output operand is not a decl or indirect ref, /* If an output operand is not a decl or indirect ref and our constraint
make a temporary to act as an intermediate. Make the asm insn allows a register, make a temporary to act as an intermediate.
write into that, then our caller will copy it to the real output Make the asm insn write into that, then our caller will copy it to
operand. Likewise for promoted variables. */ the real output operand. Likewise for promoted variables. */
if (TREE_CODE (val) == INDIRECT_REF if (TREE_CODE (val) == INDIRECT_REF
|| (TREE_CODE_CLASS (TREE_CODE (val)) == 'd' || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
&& ! (GET_CODE (DECL_RTL (val)) == REG && ! (GET_CODE (DECL_RTL (val)) == REG
&& GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))) && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
output_rtx[i] = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0); || ! allows_reg)
{
if (! allows_reg)
mark_addressable (TREE_VALUE (tail));
output_rtx[i]
= expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
error ("output number %d not directly addressable", i);
}
else else
{ {
if (TYPE_MODE (type) == BLKmode) if (TYPE_MODE (type) == BLKmode)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment