/* Generate code from machine description to extract operands from insn as rtl.
- Copyright (C) 1987-2015 Free Software Foundation, Inc.
+ Copyright (C) 1987-2020 Free Software Foundation, Inc.
This file is part of GCC.
The string for each operand describes that path to the operand and
contains `0' through `9' when going into an expression and `a' through
- `z' when going into a vector. We assume here that only the first operand
- of an rtl expression is a vector. genrecog.c makes the same assumption
- (and uses the same representation) and it is currently true. */
+ `z' then 'A' through to 'Z' when going into a vector. We assume here that
+ only the first operand of an rtl expression is a vector. genrecog.c makes
+ the same assumption (and uses the same representation) and it is currently
+ true. */
typedef char *locstr;
data that will be used to produce an extractions structure. */
-struct accum_extract
+class accum_extract
{
- vec<locstr> oplocs;
- vec<locstr> duplocs;
- vec<int> dupnums;
- vec<char> pathstr;
+public:
+ accum_extract () : oplocs (10), duplocs (10), dupnums (10), pathstr (20) {}
+
+ auto_vec<locstr> oplocs;
+ auto_vec<locstr> duplocs;
+ auto_vec<int> dupnums;
+ auto_vec<char> pathstr;
};
/* Forward declarations. */
-static void walk_rtx (md_rtx_info *, rtx, struct accum_extract *);
+static void walk_rtx (md_rtx_info *, rtx, class accum_extract *);
+
+#define UPPER_OFFSET ('A' - ('z' - 'a' + 1))
+
+/* Convert integer OPERAND into a character - either into [a-zA-Z] for vector
+ operands or [0-9] for integer operands - and push onto the end of the path
+ in ACC. */
+static void
+push_pathstr_operand (int operand, bool is_vector,
+ class accum_extract *acc)
+{
+ if (is_vector && 'a' + operand > 'z')
+ acc->pathstr.safe_push (operand + UPPER_OFFSET);
+ else if (is_vector)
+ acc->pathstr.safe_push (operand + 'a');
+ else
+ acc->pathstr.safe_push (operand + '0');
+}
static void
gen_insn (md_rtx_info *info)
unsigned int op_count, dup_count, j;
struct extraction *p;
struct code_ptr *link;
- struct accum_extract acc;
-
- acc.oplocs.create (10);
- acc.duplocs.create (10);
- acc.dupnums.create (10);
- acc.pathstr.create (20);
+ class accum_extract acc;
/* Walk the insn's pattern, remembering at all times the path
down to the walking point. */
else
for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
{
- acc.pathstr.safe_push ('a' + i);
+ push_pathstr_operand (i, true, &acc);
walk_rtx (info, XVECEXP (insn, 1, i), &acc);
acc.pathstr.pop ();
}
/* This extraction is the same as ours. Just link us in. */
link->next = p->insns;
p->insns = link;
- goto done;
+ return;
}
/* Otherwise, make a new extraction method. We stash the arrays
memcpy (p->oplocs, acc.oplocs.address (), op_count * sizeof (locstr));
memcpy (p->duplocs, acc.duplocs.address (), dup_count * sizeof (locstr));
memcpy (p->dupnums, acc.dupnums.address (), dup_count * sizeof (int));
-
- done:
- acc.oplocs.release ();
- acc.duplocs.release ();
- acc.dupnums.release ();
- acc.pathstr.release ();
}
\f
/* Helper subroutine of walk_rtx: given a vec<locstr>, an index, and a
}
static void
-walk_rtx (md_rtx_info *info, rtx x, struct accum_extract *acc)
+walk_rtx (md_rtx_info *info, rtx x, class accum_extract *acc)
{
RTX_CODE code;
- int i, len, base;
+ int i, len;
const char *fmt;
if (x == 0)
VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
VEC_char_to_string (acc->pathstr));
- base = (code == MATCH_OPERATOR ? '0' : 'a');
for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
{
- acc->pathstr.safe_push (base + i);
+ push_pathstr_operand (i, code != MATCH_OPERATOR, acc);
walk_rtx (info, XVECEXP (x, 2, i), acc);
acc->pathstr.pop ();
}
if (code == MATCH_DUP)
break;
- base = (code == MATCH_OP_DUP ? '0' : 'a');
for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
{
- acc->pathstr.safe_push (base + i);
+ push_pathstr_operand (i, code != MATCH_OP_DUP, acc);
walk_rtx (info, XVECEXP (x, 1, i), acc);
acc->pathstr.pop ();
}
{
if (fmt[i] == 'e' || fmt[i] == 'u')
{
- acc->pathstr.safe_push ('0' + i);
+ push_pathstr_operand (i, false, acc);
walk_rtx (info, XEXP (x, i), acc);
acc->pathstr.pop ();
}
int j;
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
{
- acc->pathstr.safe_push ('a' + j);
+ push_pathstr_operand (j, true, acc);
walk_rtx (info, XVECEXP (x, i, j), acc);
acc->pathstr.pop ();
}
for (i = len - 1; i >= 0 ; i--)
{
- if (ISLOWER (path[i]))
+ if (ISLOWER (path[i]) || ISUPPER (path[i]))
fputs ("XVECEXP (", stdout);
else if (ISDIGIT (path[i]))
fputs ("XEXP (", stdout);
for (i = 0; i < len; i++)
{
- if (ISLOWER (path[i]))
+ if (ISUPPER (path[i]))
+ printf (", 0, %d)", path[i] - UPPER_OFFSET);
+ else if (ISLOWER (path[i]))
printf (", 0, %d)", path[i] - 'a');
else if (ISDIGIT (path[i]))
printf (", %d)", path[i] - '0');
/* Generated automatically by the program `genextract'\n\
from the machine description file `md'. */\n\
\n\
+#define IN_TARGET_CODE 1\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
#include \"coretypes.h\"\n\
rtx pat = PATTERN (insn);\n\
int i ATTRIBUTE_UNUSED; /* only for peepholes */\n\
\n\
-#ifdef ENABLE_CHECKING\n\
- memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
- memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
-#endif\n");
+ if (flag_checking)\n\
+ {\n\
+ memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
+ memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
+ }\n");
puts ("\
switch (INSN_CODE (insn))\n\
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
unsigned int i;
struct extraction *p;