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
This commit is contained in:
parent
5326f06d7f
commit
1afbe1c4e6
|
@ -1,3 +1,11 @@
|
||||||
|
Mon Feb 1 20:00:40 1999 Richard Henderson <rth@cygnus.com>
|
||||||
|
|
||||||
|
* 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 <raeburn@cygnus.com>
|
Mon Feb 1 15:00:02 1999 Ken Raeburn <raeburn@cygnus.com>
|
||||||
|
|
||||||
Use varrays for constant-equivalence data:
|
Use varrays for constant-equivalence data:
|
||||||
|
|
32
gcc/recog.c
32
gcc/recog.c
|
@ -188,7 +188,9 @@ check_asm_operands (x)
|
||||||
for (i = 0; i < noperands; i++)
|
for (i = 0; i < noperands; i++)
|
||||||
{
|
{
|
||||||
const char *c = constraints[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'];
|
c = constraints[c[0] - '0'];
|
||||||
|
|
||||||
if (! asm_operand_ok (operands[i], c))
|
if (! asm_operand_ok (operands[i], c))
|
||||||
|
@ -1550,13 +1552,16 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes)
|
||||||
return template;
|
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
|
int
|
||||||
asm_operand_ok (op, constraint)
|
asm_operand_ok (op, constraint)
|
||||||
rtx op;
|
rtx op;
|
||||||
const char *constraint;
|
const char *constraint;
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
/* Use constrain_operands after reload. */
|
/* Use constrain_operands after reload. */
|
||||||
if (reload_completed)
|
if (reload_completed)
|
||||||
abort ();
|
abort ();
|
||||||
|
@ -1578,9 +1583,11 @@ asm_operand_ok (op, constraint)
|
||||||
|
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
/* Our caller is supposed to have given us the proper
|
/* For best results, our caller should have given us the
|
||||||
matching constraint. */
|
proper matching constraint, but we can't actually fail
|
||||||
/* abort (); */
|
the check if they didn't. Indicate that results are
|
||||||
|
inconclusive. */
|
||||||
|
result = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
|
@ -1600,15 +1607,24 @@ asm_operand_ok (op, constraint)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<':
|
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
|
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))
|
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
if (GET_CODE (op) == MEM
|
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))
|
|| GET_CODE (XEXP (op, 0)) == POST_INC))
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
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,
|
/* Given an rtx *P, if it is a sum containing an integer constant term,
|
||||||
|
|
33
gcc/stmt.c
33
gcc/stmt.c
|
@ -1251,6 +1251,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||||
int j;
|
int j;
|
||||||
int is_inout = 0;
|
int is_inout = 0;
|
||||||
int allows_reg = 0;
|
int allows_reg = 0;
|
||||||
|
int allows_mem = 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)
|
||||||
|
@ -1316,8 +1317,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '?': case '!': case '*': case '&':
|
case '?': case '!': case '*': case '&':
|
||||||
case 'V': case 'm': case 'o': case '<': case '>':
|
case 'E': case 'F': case 'G': case 'H':
|
||||||
case 'E': case 'F': case 'G': case 'H': case 'X':
|
|
||||||
case 's': case 'i': case 'n':
|
case 's': case 'i': case 'n':
|
||||||
case 'I': case 'J': case 'K': case 'L': case 'M':
|
case 'I': case 'J': case 'K': case 'L': case 'M':
|
||||||
case 'N': case 'O': case 'P': case ',':
|
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");
|
error ("matching constraint not valid in output operand");
|
||||||
break;
|
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:
|
default:
|
||||||
allows_reg = 1;
|
allows_reg = 1;
|
||||||
break;
|
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
|
Make the asm insn write into that, then our caller will copy it to
|
||||||
the real output 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
|
||||||
|
&& allows_mem)
|
||||||
|| (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
|
|| (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
|
||||||
|
&& (allows_mem || GET_CODE (DECL_RTL (val)) == REG)
|
||||||
&& ! (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)))
|
||||||
|| ! allows_reg
|
|| ! 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)
|
if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
|
||||||
error ("output number %d not directly addressable", i);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -1472,7 +1492,8 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try and find the real constraint for this dup. */
|
/* 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;
|
tree o = outputs;
|
||||||
for (j = constraint[j] - '0'; j > 0; --j)
|
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);
|
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)
|
if (allows_reg)
|
||||||
op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
|
op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
|
||||||
|
|
Loading…
Reference in New Issue