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:
parent
6ff09968f1
commit
6e7a4706fd
@ -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.
|
||||
|
@ -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"))
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user