diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-06-11 13:18:02 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-06-11 13:18:02 -0400 |
commit | d09a75ae9318ed48fb2350b84fe886d9b8bb6b01 (patch) | |
tree | 41b591b675a223b0d6e3d0827205d9cdf61a6739 | |
parent | 621061f4f3f392f3272663b98c71046d7c49692c (diff) | |
download | gcc-d09a75ae9318ed48fb2350b84fe886d9b8bb6b01.zip gcc-d09a75ae9318ed48fb2350b84fe886d9b8bb6b01.tar.gz gcc-d09a75ae9318ed48fb2350b84fe886d9b8bb6b01.tar.bz2 |
(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
-rw-r--r-- | gcc/stmt.c | 68 |
1 files changed, 50 insertions, 18 deletions
@@ -1411,41 +1411,73 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) tree type = TREE_TYPE (val); tree val1; int j; - int found_equal; + int found_equal = 0; + int allows_reg = 0; /* If there's an erroneous arg, emit no insn. */ if (TREE_TYPE (val) == error_mark_node) 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)); j++) - { - if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+') - { - error ("output operand constraint contains `+'"); - return; - } - if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=') + for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++) + switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]) + { + case '+': + error ("output operand constraint contains `+'"); + return; + + case '=': 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) { error ("output operand constraint lacks `='"); return; } - /* If an output operand is not a decl or indirect ref, - make a temporary to act as an intermediate. Make the asm insn - write into that, then our caller will copy it to the real output - operand. Likewise for promoted variables. */ + /* If an output operand is not a decl or indirect ref and our constraint + allows a register, make a temporary to act as an intermediate. + Make the asm insn write into that, then our caller will copy it to + the real output operand. Likewise for promoted variables. */ if (TREE_CODE (val) == INDIRECT_REF || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd' && ! (GET_CODE (DECL_RTL (val)) == REG - && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))) - output_rtx[i] = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0); + && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))) + || ! 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 { if (TYPE_MODE (type) == BLKmode) |