From 1afbe1c4e6d0d9a4b09d942892fe45114ada158c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 1 Feb 1999 12:03:23 -0800 Subject: [PATCH] recog.c (check_asm_operands): Treat indeterminate operand ok results as success. * recog.c (check_asm_operands): Treat indeterminate operand ok results as success. Try harder to resolve a matching constraint. * stmt.c (expand_asm_operands): Recognize when an output operand's constraint does not allow memory. Treat indeterminate operand ok results as failure. Try harder to resolve a matching constraint. From-SVN: r24959 --- gcc/ChangeLog | 8 ++++++++ gcc/recog.c | 32 ++++++++++++++++++++++++-------- gcc/stmt.c | 33 +++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 724f5b03cf6..89fd8ab40dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Mon Feb 1 20:00:40 1999 Richard Henderson + + * recog.c (check_asm_operands): Treat indeterminate operand ok + results as success. Try harder to resolve a matching constraint. + * stmt.c (expand_asm_operands): Recognize when an output operand's + constraint does not allow memory. Treat indeterminate operand ok + results as failure. Try harder to resolve a matching constraint. + Mon Feb 1 15:00:02 1999 Ken Raeburn Use varrays for constant-equivalence data: diff --git a/gcc/recog.c b/gcc/recog.c index a0dafd5ccbf..c62929c4938 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -188,7 +188,9 @@ check_asm_operands (x) for (i = 0; i < noperands; i++) { const char *c = constraints[i]; - if (ISDIGIT ((unsigned char)c[0])) + if (c[0] == '%') + c++; + if (ISDIGIT ((unsigned char)c[0]) && c[1] == '\0') c = constraints[c[0] - '0']; if (! asm_operand_ok (operands[i], c)) @@ -1550,13 +1552,16 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes) return template; } -/* Check if an asm_operand matches it's constraints. */ +/* Check if an asm_operand matches it's constraints. + Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */ int asm_operand_ok (op, constraint) rtx op; const char *constraint; { + int result = 0; + /* Use constrain_operands after reload. */ if (reload_completed) abort (); @@ -1578,9 +1583,11 @@ asm_operand_ok (op, constraint) case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - /* Our caller is supposed to have given us the proper - matching constraint. */ - /* abort (); */ + /* For best results, our caller should have given us the + proper matching constraint, but we can't actually fail + the check if they didn't. Indicate that results are + inconclusive. */ + result = -1; break; case 'p': @@ -1600,15 +1607,24 @@ asm_operand_ok (op, constraint) break; case '<': + /* ??? Before flow, auto inc/dec insns are not supposed to exist, + excepting those that expand_call created. Further, on some + machines which do not have generalized auto inc/dec, an inc/dec + is not a memory_operand. + + Match any memory and hope things are resolved after reload. */ + if (GET_CODE (op) == MEM - && (GET_CODE (XEXP (op, 0)) == PRE_DEC + && (1 + || GET_CODE (XEXP (op, 0)) == PRE_DEC || GET_CODE (XEXP (op, 0)) == POST_DEC)) return 1; break; case '>': if (GET_CODE (op) == MEM - && (GET_CODE (XEXP (op, 0)) == PRE_INC + && (1 + || GET_CODE (XEXP (op, 0)) == PRE_INC || GET_CODE (XEXP (op, 0)) == POST_INC)) return 1; break; @@ -1745,7 +1761,7 @@ asm_operand_ok (op, constraint) } } - return 0; + return result; } /* Given an rtx *P, if it is a sum containing an integer constant term, diff --git a/gcc/stmt.c b/gcc/stmt.c index cc0419d2a97..ab7a5cfdd21 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1251,6 +1251,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) int j; int is_inout = 0; int allows_reg = 0; + int allows_mem = 0; /* If there's an erroneous arg, emit no insn. */ if (TREE_TYPE (val) == error_mark_node) @@ -1316,8 +1317,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) break; case '?': case '!': case '*': case '&': - case 'V': case 'm': case 'o': case '<': case '>': - case 'E': case 'F': case 'G': case 'H': case 'X': + case 'E': case 'F': case 'G': case 'H': case 's': case 'i': case 'n': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case ',': @@ -1331,7 +1331,23 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) error ("matching constraint not valid in output operand"); break; - case 'p': case 'g': case 'r': + case 'V': case 'm': case 'o': + allows_mem = 1; + break; + + case '<': case '>': + /* ??? Before flow, auto inc/dec insns are not supposed to exist, + excepting those that expand_call created. So match memory + and hope. */ + allows_mem = 1; + break; + + case 'g': case 'X': + allows_reg = 1; + allows_mem = 1; + break; + + case 'p': case 'r': default: allows_reg = 1; break; @@ -1342,8 +1358,10 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) 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 + if ((TREE_CODE (val) == INDIRECT_REF + && allows_mem) || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd' + && (allows_mem || GET_CODE (DECL_RTL (val)) == REG) && ! (GET_CODE (DECL_RTL (val)) == REG && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type))) || ! allows_reg @@ -1358,6 +1376,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) if (! allows_reg && GET_CODE (output_rtx[i]) != MEM) error ("output number %d not directly addressable", i); + if (! allows_mem && GET_CODE (output_rtx[i]) == MEM) + error ("output number %d not restored to memory", i); } else { @@ -1472,7 +1492,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) } /* Try and find the real constraint for this dup. */ - if (j == 0 && c_len == 1) + if ((j == 0 && c_len == 1) + || (j == 1 && c_len == 2 && constraint[0] == '%')) { tree o = outputs; for (j = constraint[j] - '0'; j > 0; --j) @@ -1502,7 +1523,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0); - if (! asm_operand_ok (op, constraint)) + if (asm_operand_ok (op, constraint) <= 0) { if (allows_reg) op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);