aboutsummaryrefslogtreecommitdiff
path: root/gcc/genrecog.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-07-15 17:28:20 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-07-15 17:28:20 -0700
commit9e9f3eded6a1f549433a7821c448c8eefb0cbe99 (patch)
tree3979093e16abc21060c0838e4098170a76535cc1 /gcc/genrecog.c
parent25dfa34d5009fcde9c21fb3956e36c1d13f810f4 (diff)
downloadgcc-9e9f3eded6a1f549433a7821c448c8eefb0cbe99.zip
gcc-9e9f3eded6a1f549433a7821c448c8eefb0cbe99.tar.gz
gcc-9e9f3eded6a1f549433a7821c448c8eefb0cbe99.tar.bz2
machmode.def (Pmode): Redefine if GENERATOR_FILE.
* machmode.def (Pmode): Redefine if GENERATOR_FILE. * genrecog.c (maybe_both_true_mode): New. (maybe_both_true_2): Use it. (write_switch): Don't put Pmode in a switch. * rtl.c (mode arrays): Don't explicitly size them. From-SVN: r44029
Diffstat (limited to 'gcc/genrecog.c')
-rw-r--r--gcc/genrecog.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 8dfaa61..c3a7fea 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -238,6 +238,8 @@ static void validate_pattern
static struct decision *add_to_sequence
PARAMS ((rtx, struct decision_head *, const char *, enum routine_type, int));
+static int maybe_both_true_mode
+ PARAMS ((enum machine_mode, enum machine_mode));
static int maybe_both_true_2
PARAMS ((struct decision_test *, struct decision_test *));
static int maybe_both_true_1
@@ -1054,6 +1056,29 @@ add_to_sequence (pattern, last, position, insn_type, top)
return sub;
}
+/* A subroutine of maybe_both_true; compares two modes.
+ Returns > 0 for "definitely both true" and < 0 for "maybe both true". */
+
+static int
+maybe_both_true_mode (m1, m2)
+ enum machine_mode m1, m2;
+{
+ enum mode_class other_mode_class;
+
+ /* Pmode is not a distinct mode. We do know that it is
+ either MODE_INT or MODE_PARTIAL_INT though. */
+ if (m1 == Pmode)
+ other_mode_class = GET_MODE_CLASS (m2);
+ else if (m2 == Pmode)
+ other_mode_class = GET_MODE_CLASS (m1);
+ else
+ return m1 == m2;
+
+ return (other_mode_class == MODE_INT
+ || other_mode_class == MODE_PARTIAL_INT
+ ? -1 : 0);
+}
+
/* A subroutine of maybe_both_true; examines only one test.
Returns > 0 for "definitely both true" and < 0 for "maybe both true". */
@@ -1066,7 +1091,7 @@ maybe_both_true_2 (d1, d2)
switch (d1->type)
{
case DT_mode:
- return d1->u.mode == d2->u.mode;
+ return maybe_both_true_mode (d1->u.mode, d2->u.mode);
case DT_code:
return d1->u.code == d2->u.code;
@@ -1102,7 +1127,7 @@ maybe_both_true_2 (d1, d2)
{
if (d2->type == DT_mode)
{
- if (d1->u.pred.mode != d2->u.mode
+ if (maybe_both_true_mode (d1->u.pred.mode, d2->u.mode) == 0
/* The mode of an address_operand predicate is the
mode of the memory, not the operand. It can only
be used for testing the predicate, so we must
@@ -1884,6 +1909,10 @@ write_switch (start, depth)
|| type == DT_elt_one_int
|| type == DT_elt_zero_wide_safe)
{
+ /* Pmode may not be a compile-time constant. */
+ if (type == DT_mode && p->tests->u.mode == Pmode)
+ return p;
+
printf (" switch (");
switch (type)
{
@@ -1919,6 +1948,10 @@ write_switch (start, depth)
if (nodes_identical_1 (p->tests, q->tests))
goto case_done;
+ /* Pmode may not be a compile-time constant. */
+ if (type == DT_mode && p->tests->u.mode == Pmode)
+ goto case_done;
+
if (p != start && p->need_label && needs_label == NULL)
needs_label = p;