r110130@banpei: zack | 2006-01-22 14:52:43 -0800

r110130@banpei:  zack | 2006-01-22 14:52:43 -0800
 	* rtl.def (match_code): Add second argument.
 	* genpreds.c (write_extract_subexp): New function.
 	(write_match_code): Add path argument.  Use write_extract_subexp.
 	(write_predicate_expr): Pass path to write_match_code.
 	(mark_mode_tests): MATCH_CODE applied to a subexpression does
 	not perform a mode test.
 	* genrecog.c (compute_predicate_codes): MATCH_CODE applied to
 	a subexpression does not constrain the top-level code set.
 	* read-rtl.c (read_rtx_variadic): New function.
 	(read_rtx_1): Use it; allow AND and IOR to be variadic.
 	* doc/md.texi: Document new notation.
 	* config/i386/predicates.md (cmpsi_operand_1): Fold into ...
 	(cmpsi_operand): ... here, using new notation.

From-SVN: r110126
This commit is contained in:
Zack Weinberg 2006-01-23 15:16:19 +00:00 committed by Zack Weinberg
parent 6ff09968f1
commit 6e7a4706fd
7 changed files with 159 additions and 31 deletions

View File

@ -1,3 +1,19 @@
2006-01-22 Zack Weinberg <zackw@panix.com>
* rtl.def (match_code): Add second argument.
* genpreds.c (write_extract_subexp): New function.
(write_match_code): Add path argument. Use write_extract_subexp.
(write_predicate_expr): Pass path to write_match_code.
(mark_mode_tests): MATCH_CODE applied to a subexpression does
not perform a mode test.
* genrecog.c (compute_predicate_codes): MATCH_CODE applied to
a subexpression does not constrain the top-level code set.
* read-rtl.c (read_rtx_variadic): New function.
(read_rtx_1): Use it; allow AND and IOR to be variadic.
* doc/md.texi: Document new notation.
* config/i386/predicates.md (cmpsi_operand_1): Fold into ...
(cmpsi_operand): ... here, using new notation.
2006-01-22 Zack Weinberg <zackw@panix.com>
* varray.c: Remove GENERATOR_FILE #ifdefs.

View File

@ -931,21 +931,16 @@
;; ??? It seems likely that this will only work because cmpsi is an
;; expander, and no actual insns use this.
(define_predicate "cmpsi_operand_1"
(match_code "and")
{
return (GET_MODE (op) == SImode
&& GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
&& GET_CODE (XEXP (XEXP (op, 0), 2)) == CONST_INT
&& INTVAL (XEXP (XEXP (op, 0), 1)) == 8
&& INTVAL (XEXP (XEXP (op, 0), 2)) == 8
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
})
(define_predicate "cmpsi_operand"
(ior (match_operand 0 "nonimmediate_operand")
(match_operand 0 "cmpsi_operand_1")))
(and (match_code "and")
(match_code "zero_extract" "0")
(match_code "const_int" "1")
(match_code "const_int" "01")
(match_code "const_int" "02")
(match_test "INTVAL (XEXP (XEXP (op, 0), 1)) == 8")
(match_test "INTVAL (XEXP (XEXP (op, 0), 2)) == 8")
)))
(define_predicate "compare_operator"
(match_code "compare"))

View File

@ -898,9 +898,27 @@ limitations in @command{genrecog}, you can only refer to generic
predicates and predicates that have already been defined.
@item MATCH_CODE
This expression has one operand, a string constant containing a
comma-separated list of RTX code names (in lower case). It evaluates
to true if @var{op} has any of the listed codes.
This expression evaluates to true if @var{op} or a specified
subexpression of @var{op} has one of a given list of RTX codes.
The first operand of this expression is a string constant containing a
comma-separated list of RTX code names (in lower case). These are the
codes for which the @code{MATCH_CODE} will be true.
The second operand is a string constant which indicates what
subexpression of @var{op} to examine. If it is absent or the empty
string, @var{op} itself is examined. Otherwise, the string constant
must be a sequence of digits and/or lowercase letters. Each character
indicates a subexpression to extract from the current expression; for
the first character this is @var{op}, for the second and subsequent
characters it is the result of the previous character. A digit
@var{n} extracts @samp{@w{XEXP (@var{e}, @var{n})}}; a letter @var{l}
extracts @samp{@w{XVECEXP (@var{e}, 0, @var{n})}} where @var{n} is the
alphabetic ordinal of @var{l} (0 for `a', 1 for 'b', and so on). The
@code{MATCH_CODE} then examines the RTX code of the subexpression
extracted by the complete string. It is not possible to extract
components of an @code{rtvec} that is not at position 0 within its RTX
object.
@item MATCH_TEST
This expression has one operand, a string constant containing a C
@ -915,7 +933,10 @@ evaluates to true if the C expression evaluates to a nonzero value.
@itemx IF_THEN_ELSE
The basic @samp{MATCH_} expressions can be combined using these
logical operators, which have the semantics of the C operators
@samp{&&}, @samp{||}, @samp{!}, and @samp{@w{? :}} respectively.
@samp{&&}, @samp{||}, @samp{!}, and @samp{@w{? :}} respectively. As
in Common Lisp, you may give an @code{AND} or @code{IOR} expression an
arbitrary number of arguments; this has exactly the same effect as
writing a chain of two-argument @code{AND} or @code{IOR} expressions.
@end table
@item

View File

@ -148,11 +148,11 @@ write_predicate_subfunction (struct pred_data *p)
/* Given an RTL expression EXP, find all subexpressions which we may
assume to perform mode tests. Normal MATCH_OPERAND does;
MATCH_CODE does if and only if it accepts CONST_INT or
CONST_DOUBLE; and we have to assume that MATCH_TEST does not.
These combine in almost-boolean fashion - the only exception is
that (not X) must be assumed not to perform a mode test, whether or
not X does.
MATCH_CODE does if it applies to the whole expression and accepts
CONST_INT or CONST_DOUBLE; and we have to assume that MATCH_TEST
does not. These combine in almost-boolean fashion - the only
exception is that (not X) must be assumed not to perform a mode
test, whether or not X does.
The mark is the RTL /v flag, which is true for subexpressions which
do *not* perform mode tests.
@ -174,8 +174,9 @@ mark_mode_tests (rtx exp)
break;
case MATCH_CODE:
if (!strstr (XSTR (exp, 0), "const_int")
&& !strstr (XSTR (exp, 0), "const_double"))
if (XSTR (exp, 1)[0] != '\0'
|| (!strstr (XSTR (exp, 0), "const_int")
&& !strstr (XSTR (exp, 0), "const_double")))
NO_MODE_TEST (exp) = 1;
break;
@ -305,17 +306,56 @@ add_mode_tests (struct pred_data *p)
*pos = and_exp;
}
/* PATH is a string describing a path from the root of an RTL
expression to an inner subexpression to be tested. Output
code which computes the subexpression from the variable
holding the root of the expression. */
static void
write_extract_subexp (const char *path)
{
int len = strlen (path);
int i;
/* We first write out the operations (XEXP or XVECEXP) in reverse
order, then write "op", then the indices in forward order. */
for (i = len - 1; i >= 0; i--)
{
if (ISLOWER (path[i]))
fputs ("XVECEXP (", stdout);
else if (ISDIGIT (path[i]))
fputs ("XEXP (", stdout);
else
{
error ("bad character in path string '%s'", path);
return;
}
}
fputs ("op", stdout);
for (i = 0; i < len; i++)
{
if (ISLOWER (path[i]))
printf (", 0, %d)", path[i] - 'a');
else if (ISDIGIT (path[i]))
printf (", %d)", path[i] - '0');
else
gcc_unreachable ();
}
}
/* CODES is a list of RTX codes. Write out an expression which
determines whether the operand has one of those codes. */
static void
write_match_code (const char *codes)
write_match_code (const char *path, const char *codes)
{
const char *code;
while ((code = scan_comma_elt (&codes)) != 0)
{
fputs ("GET_CODE (op) == ", stdout);
fputs ("GET_CODE (", stdout);
write_extract_subexp (path);
fputs (") == ", stdout);
while (code < codes)
{
putchar (TOUPPER (*code));
@ -374,7 +414,7 @@ write_predicate_expr (const char *name, rtx exp)
break;
case MATCH_CODE:
write_match_code (XSTR (exp, 0));
write_match_code (XSTR (exp, 1), XSTR (exp, 0));
break;
case MATCH_TEST:

View File

@ -270,7 +270,15 @@ compute_predicate_codes (rtx exp, char codes[NUM_RTX_CODE])
break;
case MATCH_CODE:
/* MATCH_CODE allows a specified list of codes. */
/* MATCH_CODE allows a specified list of codes. However, if it
does not apply to the top level of the expression, it does not
constrain the set of codes for the top level. */
if (XSTR (exp, 1)[0] != '\0')
{
memset (codes, Y, NUM_RTX_CODE);
break;
}
memset (codes, N, NUM_RTX_CODE);
{
const char *next_code = XSTR (exp, 0);

View File

@ -145,6 +145,7 @@ static int find_macro (struct macro_group *, const char *, FILE *);
static struct mapping *read_mapping (struct macro_group *, htab_t, FILE *);
static void check_code_macro (struct mapping *, FILE *);
static rtx read_rtx_1 (FILE *, struct map_value **);
static rtx read_rtx_variadic (FILE *, struct map_value **, rtx);
/* The mode and code macro structures. */
static struct macro_group modes, codes;
@ -1696,7 +1697,49 @@ read_rtx_1 (FILE *infile, struct map_value **mode_maps)
c = read_skip_spaces (infile);
if (c != ')')
fatal_expected_char (infile, ')', c);
{
/* Syntactic sugar for AND and IOR, allowing Lisp-like
arbitrary number of arguments for them. */
if (c == '(' && (GET_CODE (return_rtx) == AND
|| GET_CODE (return_rtx) == IOR))
return read_rtx_variadic (infile, mode_maps, return_rtx);
else
fatal_expected_char (infile, ')', c);
}
return return_rtx;
}
/* Mutually recursive subroutine of read_rtx which reads
(thing x1 x2 x3 ...) and produces RTL as if
(thing x1 (thing x2 (thing x3 ...))) had been written.
When called, FORM is (thing x1 x2), and the file position
is just past the leading parenthesis of x3. Only works
for THINGs which are dyadic expressions, e.g. AND, IOR. */
static rtx
read_rtx_variadic (FILE *infile, struct map_value **mode_maps, rtx form)
{
char c = '(';
rtx p = form, q;
do
{
ungetc (c, infile);
q = rtx_alloc (GET_CODE (p));
PUT_MODE (q, GET_MODE (p));
XEXP (q, 0) = XEXP (p, 1);
XEXP (q, 1) = read_rtx_1 (infile, mode_maps);
XEXP (p, 1) = q;
p = q;
c = read_skip_spaces (infile);
}
while (c == '(');
if (c != ')')
fatal_expected_char (infile, ')', c);
return form;
}

View File

@ -727,8 +727,13 @@ DEF_RTL_EXPR(MATCH_PAR_DUP, "match_par_dup", "iE", RTX_MATCH)
/* Appears only in define_predicate/define_special_predicate
expressions. Evaluates true only if the operand has an RTX code
from the set given by the argument (a comma-separated list). */
DEF_RTL_EXPR(MATCH_CODE, "match_code", "s", RTX_MATCH)
from the set given by the argument (a comma-separated list). If the
second argument is present and nonempty, it is a sequence of digits
and/or letters which indicates the subexpression to test, using the
same syntax as genextract/genrecog's location strings: 0-9 for
XEXP (op, n), a-z for XVECEXP (op, 0, n); each character applies to
the result of the one before it. */
DEF_RTL_EXPR(MATCH_CODE, "match_code", "ss", RTX_MATCH)
/* Appears only in define_predicate/define_special_predicate
expressions. The argument is a C expression to be injected at this