aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-04-17 18:42:49 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1992-04-17 18:42:49 -0400
commit9e21be9dfc4f91607f13dcda03d6f2c977ce3d0a (patch)
tree2516da4b887ca63cd8692699a957cce24e25878e
parentc8470713623c22b28edb6249520cdf78df504433 (diff)
downloadgcc-9e21be9dfc4f91607f13dcda03d6f2c977ce3d0a.zip
gcc-9e21be9dfc4f91607f13dcda03d6f2c977ce3d0a.tar.gz
gcc-9e21be9dfc4f91607f13dcda03d6f2c977ce3d0a.tar.bz2
*** empty log message ***
From-SVN: r768
-rw-r--r--gcc/recog.c61
1 files changed, 53 insertions, 8 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index 640bc0b..b986811 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1599,6 +1599,9 @@ constrain_operands (insn_code_num, strict)
int strict;
{
char *constraints[MAX_RECOG_OPERANDS];
+ int matching_operands[MAX_RECOG_OPERANDS];
+ enum op_type {OP_IN, OP_OUT, OP_INOUT} op_types[MAX_RECOG_OPERANDS];
+ int earlyclobber[MAX_RECOG_OPERANDS];
register int c;
int noperands = insn_n_operands[insn_code_num];
@@ -1610,7 +1613,11 @@ constrain_operands (insn_code_num, strict)
return 1;
for (c = 0; c < noperands; c++)
- constraints[c] = insn_operand_constraint[insn_code_num][c];
+ {
+ constraints[c] = insn_operand_constraint[insn_code_num][c];
+ matching_operands[c] = -1;
+ op_types[c] = OP_IN;
+ }
which_alternative = 0;
@@ -1629,6 +1636,8 @@ constrain_operands (insn_code_num, strict)
int win = 0;
int val;
+ earlyclobber[opno] = 0;
+
if (GET_CODE (op) == SUBREG)
{
if (GET_CODE (SUBREG_REG (op)) == REG
@@ -1645,16 +1654,25 @@ constrain_operands (insn_code_num, strict)
while (*p && (c = *p++) != ',')
switch (c)
{
- case '=':
- case '+':
case '?':
case '#':
- case '&':
case '!':
case '*':
case '%':
break;
+ case '=':
+ op_types[opno] = OP_OUT;
+ break;
+
+ case '+':
+ op_types[opno] = OP_INOUT;
+ break;
+
+ case '&':
+ earlyclobber[opno] = 1;
+ break;
+
case '0':
case '1':
case '2':
@@ -1674,6 +1692,9 @@ constrain_operands (insn_code_num, strict)
val = operands_match_p (recog_operand[c - '0'],
recog_operand[opno]);
+ matching_operands[opno] = c - '0';
+ matching_operands[c - '0'] = opno;
+
if (val != 0)
win = 1;
/* If output is *x and input is *--x,
@@ -1850,12 +1871,36 @@ constrain_operands (insn_code_num, strict)
Change whichever operands this alternative says to change. */
if (! lose)
{
- while (--funny_match_index >= 0)
+ int opno, eopno;
+
+ /* See if any earlyclobber operand conflicts with some other
+ operand. */
+
+ if (strict > 0)
+ for (eopno = 0; eopno < noperands; eopno++)
+ if (earlyclobber[eopno])
+ for (opno = 0; opno < noperands; opno++)
+ if ((GET_CODE (recog_operand[opno]) == MEM
+ || op_types[opno] != OP_OUT)
+ && opno != eopno
+ && constraints[opno] != 0
+ && ! (matching_operands[opno] == eopno
+ && rtx_equal_p (recog_operand[opno],
+ recog_operand[eopno]))
+ && ! safe_from_earlyclobber (recog_operand[opno],
+ recog_operand[eopno]))
+ lose = 1;
+
+ if (! lose)
{
- recog_operand[funny_match[funny_match_index].other]
- = recog_operand[funny_match[funny_match_index].this];
+ while (--funny_match_index >= 0)
+ {
+ recog_operand[funny_match[funny_match_index].other]
+ = recog_operand[funny_match[funny_match_index].this];
+ }
+
+ return 1;
}
- return 1;
}
which_alternative++;