Commit cff1b7e0 by Richard Sandiford Committed by Richard Sandiford

recog.h (insn_operand_data): Add an "allows_mem" field.

gcc/
	* recog.h (insn_operand_data): Add an "allows_mem" field.
	* genoutput.c (output_operand_data): Initialize it.
	* optabs.c (maybe_legitimize_operand_same_code): New function.
	(maybe_legitimize_operand): Use it when matching the original
	op->value.

From-SVN: r172316
parent 77059241
2011-04-12 Richard Sandiford <richard.sandiford@linaro.org> 2011-04-12 Richard Sandiford <richard.sandiford@linaro.org>
* recog.h (insn_operand_data): Add an "allows_mem" field.
* genoutput.c (output_operand_data): Initialize it.
* optabs.c (maybe_legitimize_operand_same_code): New function.
(maybe_legitimize_operand): Use it when matching the original
op->value.
2011-04-12 Richard Sandiford <richard.sandiford@linaro.org>
* genpreds.c (process_define_predicate): Move most processing * genpreds.c (process_define_predicate): Move most processing
to gensupport.c. Continue to validate the expression. to gensupport.c. Continue to validate the expression.
* genrecog.c (did_you_mean_codes, compute_predicate_codes) * genrecog.c (did_you_mean_codes, compute_predicate_codes)
......
...@@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see
MATCH_OPERAND; it is zero for operands that should not be changed during MATCH_OPERAND; it is zero for operands that should not be changed during
register elimination such as MATCH_OPERATORs. register elimination such as MATCH_OPERATORs.
g. `allows_mem', is true for operands that accept MEM rtxes.
The code number of an insn is simply its position in the machine The code number of an insn is simply its position in the machine
description; code numbers are assigned sequentially to entries in description; code numbers are assigned sequentially to entries in
the description, starting with code number 0. the description, starting with code number 0.
...@@ -256,6 +258,8 @@ output_operand_data (void) ...@@ -256,6 +258,8 @@ output_operand_data (void)
for (d = odata; d; d = d->next) for (d = odata; d; d = d->next)
{ {
struct pred_data *pred;
printf (" {\n"); printf (" {\n");
printf (" %s,\n", printf (" %s,\n",
...@@ -269,7 +273,12 @@ output_operand_data (void) ...@@ -269,7 +273,12 @@ output_operand_data (void)
printf (" %d,\n", d->constraint == NULL ? 1 : 0); printf (" %d,\n", d->constraint == NULL ? 1 : 0);
printf (" %d\n", d->eliminable); printf (" %d,\n", d->eliminable);
pred = NULL;
if (d->predicate)
pred = lookup_predicate (d->predicate);
printf (" %d\n", pred && pred->codes[MEM]);
printf(" },\n"); printf(" },\n");
} }
......
...@@ -7001,6 +7001,36 @@ insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand) ...@@ -7001,6 +7001,36 @@ insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
(operand, insn_data[(int) icode].operand[opno].mode))); (operand, insn_data[(int) icode].operand[opno].mode)));
} }
/* Like maybe_legitimize_operand, but do not change the code of the
current rtx value. */
static bool
maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
struct expand_operand *op)
{
/* See if the operand matches in its current form. */
if (insn_operand_matches (icode, opno, op->value))
return true;
/* If the operand is a memory, try forcing the address into a register. */
if (MEM_P (op->value) && insn_data[(int) icode].operand[opno].allows_mem)
{
rtx addr, mem, last;
last = get_last_insn ();
addr = force_reg (Pmode, XEXP (op->value, 0));
mem = replace_equiv_address (op->value, addr);
if (insn_operand_matches (icode, opno, mem))
{
op->value = mem;
return true;
}
delete_insns_since (last);
}
return false;
}
/* Try to make OP match operand OPNO of instruction ICODE. Return true /* Try to make OP match operand OPNO of instruction ICODE. Return true
on success, storing the new operand value back in OP. */ on success, storing the new operand value back in OP. */
...@@ -7011,21 +7041,24 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7011,21 +7041,24 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
enum machine_mode mode, imode; enum machine_mode mode, imode;
bool old_volatile_ok, result; bool old_volatile_ok, result;
old_volatile_ok = volatile_ok;
mode = op->mode; mode = op->mode;
result = false;
switch (op->type) switch (op->type)
{ {
case EXPAND_FIXED: case EXPAND_FIXED:
old_volatile_ok = volatile_ok;
volatile_ok = true; volatile_ok = true;
break; result = maybe_legitimize_operand_same_code (icode, opno, op);
volatile_ok = old_volatile_ok;
return result;
case EXPAND_OUTPUT: case EXPAND_OUTPUT:
gcc_assert (mode != VOIDmode); gcc_assert (mode != VOIDmode);
if (!op->value if (op->value
|| op->value == const0_rtx && op->value != const0_rtx
|| GET_MODE (op->value) != mode && GET_MODE (op->value) == mode
|| !insn_operand_matches (icode, opno, op->value)) && maybe_legitimize_operand_same_code (icode, opno, op))
return true;
op->value = gen_reg_rtx (mode); op->value = gen_reg_rtx (mode);
break; break;
...@@ -7034,8 +7067,9 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7034,8 +7067,9 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
gcc_assert (mode != VOIDmode); gcc_assert (mode != VOIDmode);
gcc_assert (GET_MODE (op->value) == VOIDmode gcc_assert (GET_MODE (op->value) == VOIDmode
|| GET_MODE (op->value) == mode); || GET_MODE (op->value) == mode);
result = insn_operand_matches (icode, opno, op->value); if (maybe_legitimize_operand_same_code (icode, opno, op))
if (!result) return true;
op->value = copy_to_mode_reg (mode, op->value); op->value = copy_to_mode_reg (mode, op->value);
break; break;
...@@ -7070,10 +7104,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno, ...@@ -7070,10 +7104,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
goto input; goto input;
break; break;
} }
if (!result) return insn_operand_matches (icode, opno, op->value);
result = insn_operand_matches (icode, opno, op->value);
volatile_ok = old_volatile_ok;
return result;
} }
/* Make OP describe an input operand that should have the same value /* Make OP describe an input operand that should have the same value
......
...@@ -272,6 +272,8 @@ struct insn_operand_data ...@@ -272,6 +272,8 @@ struct insn_operand_data
const char is_operator; const char is_operator;
const char eliminable; const char eliminable;
const char allows_mem;
}; };
/* Legal values for insn_data.output_format. Indicate what type of data /* Legal values for insn_data.output_format. Indicate what type of data
......
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