/* Generate code from machine description to recognize rtl as insns.
- Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
This file is part of GNU CC.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This program is used to produce insn-recog.c, which contains
static int next_insn_code;
/* Similar, but counts all expressions in the MD file; used for
- error messages. */
+ error messages. */
static int next_index;
{"push_operand", {MEM}},
{"memory_operand", {SUBREG, MEM}},
{"indirect_operand", {SUBREG, MEM}},
- {"comparison_operation", {EQ, NE, LE, LT, GE, LT, LEU, LTU, GEU, GTU}},
+ {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU}},
{"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
LABEL_REF, SUBREG, REG, MEM}}};
Finally, if we know that the predicate does not allow CONST_INT, we
know that the only way the predicate can match is if the modes match
- (here we use the kluge of relying on the fact that "address_operand"
+ (here we use the kludge of relying on the fact that "address_operand"
accepts CONST_INT; otherwise, it would have to be a special case),
so we can test the mode (but we need not). This fact should
considerably simplify the generated code. */
if (new->tests)
- for (i = 0; i < NUM_KNOWN_PREDS; i++)
- if (! strcmp (preds[i].name, new->tests))
- {
- int j;
- int allows_const_int = 0;
+ {
+ for (i = 0; i < NUM_KNOWN_PREDS; i++)
+ if (! strcmp (preds[i].name, new->tests))
+ {
+ int j;
+ int allows_const_int = 0;
- new->pred = i;
+ new->pred = i;
- if (preds[i].codes[1] == 0 && new->code == UNKNOWN)
- {
- new->code = preds[i].codes[0];
- if (! strcmp ("const_int_operand", new->tests))
- new->tests = 0, new->pred = -1;
- }
+ if (preds[i].codes[1] == 0 && new->code == UNKNOWN)
+ {
+ new->code = preds[i].codes[0];
+ if (! strcmp ("const_int_operand", new->tests))
+ new->tests = 0, new->pred = -1;
+ }
- for (j = 0; j < NUM_RTX_CODE && preds[i].codes[j] != 0; j++)
- if (preds[i].codes[j] == CONST_INT)
- allows_const_int = 1;
+ for (j = 0; j < NUM_RTX_CODE && preds[i].codes[j] != 0; j++)
+ if (preds[i].codes[j] == CONST_INT)
+ allows_const_int = 1;
- if (! allows_const_int)
- new->enforce_mode = new->ignore_mode= 1;
+ if (! allows_const_int)
+ new->enforce_mode = new->ignore_mode= 1;
- break;
- }
+ break;
+ }
+
+#ifdef PREDICATE_CODES
+ /* If the port has a list of the predicates it uses but omits
+ one, warn. */
+ if (i == NUM_KNOWN_PREDS)
+ fprintf (stderr, "Warning: `%s' not in PREDICATE_CODES\n",
+ new->tests);
+#endif
+ }
if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
{
if (GET_CODE (XEXP (pattern, 0)) == CC0)
break;
- /* ... fall through ... */
+ /* ... fall through ... */
case COMPARE:
/* Enforce the mode on the first operand to avoid ambiguous insns. */
struct decision *p1, *p2;
/* If they are both to test modes and the modes are different, they aren't
- both true. Similarly for codes, integer elements, and vector lengths. */
+ both true. Similarly for codes, integer elements, and vector lengths. */
if ((d1->enforce_mode && d2->enforce_mode
&& d1->mode != VOIDmode && d2->mode != VOIDmode && d1->mode != d2->mode)
int initial;
{
int size = 0;
- struct decision *node, *sub;
+ struct decision *sub;
for (sub = head.first; sub; sub = sub->next)
size += 1 + break_out_subroutines (sub->success, type, 0);
seen any of the codes that are valid for the predicate, we
can write a series of "case" statement, one for each possible
code. Since we are already in a switch, these redundant tests
- are very cheap and will reduce the number of predicate called. */
+ are very cheap and will reduce the number of predicate called. */
if (p->pred >= 0)
{
}
/* Now that most mode and code tests have been done, we can write out
- a label for an inner node, if we haven't already. */
+ a label for an inner node, if we haven't already. */
if (p->label_needed)
printf ("%sL%d:\n", indents[indent - 2], p->number);
if (p->test_elt_one_int)
printf ("XINT (x%d, 1) == %d && ", depth, p->elt_one_int);
if (p->test_elt_zero_wide)
- printf (
+ {
+ /* Set offset to 1 iff the number might get propagated to
+ unsigned long by ANSI C rules, else 0.
+ Prospective hosts are required to have at least 32 bit
+ ints, and integer constants in machine descriptions
+ must fit in 32 bit, thus it suffices to check only
+ for 1 << 31 . */
+ HOST_WIDE_INT offset = p->elt_zero_wide == -2147483647 - 1;
+ printf (
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- "XWINT (x%d, 0) == %d && ",
+ "XWINT (x%d, 0) == %d%s && ",
#else
- "XWINT (x%d, 0) == %ld && ",
+ "XWINT (x%d, 0) == %ld%s && ",
#endif
- depth, p->elt_zero_wide);
+ depth, p->elt_zero_wide + offset, offset ? "-1" : "");
+ }
if (p->veclen)
printf ("XVECLEN (x%d, 0) == %d && ", depth, p->veclen);
if (p->dupno >= 0)