read-rtl.c: split out read_rtx_operand from read_rtx_code
gcc/ChangeLog: * read-rtl.c (read_rtx_code): Rename local "i" to "idx", and use "c" instead when parsing characters. Move operand parsing into... (read_rtx_operand): ...this new function, renaming "i" to "idx", and tightening the scope of various locals. From-SVN: r240502
This commit is contained in:
parent
2fd88f4ff2
commit
f22735ae61
@ -1,3 +1,10 @@
|
||||
2016-09-26 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* read-rtl.c (read_rtx_code): Rename local "i" to "idx", and use
|
||||
"c" instead when parsing characters. Move operand parsing into...
|
||||
(read_rtx_operand): ...this new function, renaming "i" to "idx",
|
||||
and tightening the scope of various locals.
|
||||
|
||||
2016-09-26 LH Mouse <lh_mouse@126.com>
|
||||
|
||||
* config/i386/cygming.h (ASM_OUTPUT_DWARF_OFFSET): Fix typo.
|
||||
|
404
gcc/read-rtl.c
404
gcc/read-rtl.c
@ -107,6 +107,7 @@ const char *current_iterator_name;
|
||||
|
||||
static void validate_const_int (const char *);
|
||||
static rtx read_rtx_code (const char *);
|
||||
static void read_rtx_operand (rtx, int);
|
||||
static rtx read_nested_rtx (void);
|
||||
static rtx read_rtx_variadic (rtx);
|
||||
|
||||
@ -1089,17 +1090,12 @@ read_rtx (const char *rtx_name, vec<rtx> *rtxen)
|
||||
static rtx
|
||||
read_rtx_code (const char *code_name)
|
||||
{
|
||||
int i;
|
||||
RTX_CODE code;
|
||||
struct mapping *iterator, *m;
|
||||
struct mapping *iterator;
|
||||
const char *format_ptr;
|
||||
struct md_name name;
|
||||
rtx return_rtx;
|
||||
int c;
|
||||
HOST_WIDE_INT tmp_wide;
|
||||
char *str;
|
||||
char *start, *end, *ptr;
|
||||
char tmpstr[256];
|
||||
|
||||
/* Linked list structure for making RTXs: */
|
||||
struct rtx_list
|
||||
@ -1128,199 +1124,17 @@ read_rtx_code (const char *code_name)
|
||||
/* If what follows is `: mode ', read it and
|
||||
store the mode in the rtx. */
|
||||
|
||||
i = read_skip_spaces ();
|
||||
if (i == ':')
|
||||
c = read_skip_spaces ();
|
||||
if (c == ':')
|
||||
{
|
||||
read_name (&name);
|
||||
record_potential_iterator_use (&modes, return_rtx, name.string);
|
||||
}
|
||||
else
|
||||
unread_char (i);
|
||||
unread_char (c);
|
||||
|
||||
for (i = 0; format_ptr[i] != 0; i++)
|
||||
switch (format_ptr[i])
|
||||
{
|
||||
/* 0 means a field for internal use only.
|
||||
Don't expect it to be present in the input. */
|
||||
case '0':
|
||||
if (code == REG)
|
||||
ORIGINAL_REGNO (return_rtx) = REGNO (return_rtx);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'u':
|
||||
XEXP (return_rtx, i) = read_nested_rtx ();
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
/* 'V' is an optional vector: if a closeparen follows,
|
||||
just store NULL for this element. */
|
||||
c = read_skip_spaces ();
|
||||
unread_char (c);
|
||||
if (c == ')')
|
||||
{
|
||||
XVEC (return_rtx, i) = 0;
|
||||
break;
|
||||
}
|
||||
/* Now process the vector. */
|
||||
/* FALLTHRU */
|
||||
|
||||
case 'E':
|
||||
{
|
||||
/* Obstack to store scratch vector in. */
|
||||
struct obstack vector_stack;
|
||||
int list_counter = 0;
|
||||
rtvec return_vec = NULL_RTVEC;
|
||||
|
||||
require_char_ws ('[');
|
||||
|
||||
/* Add expressions to a list, while keeping a count. */
|
||||
obstack_init (&vector_stack);
|
||||
while ((c = read_skip_spaces ()) && c != ']')
|
||||
{
|
||||
if (c == EOF)
|
||||
fatal_expected_char (']', c);
|
||||
unread_char (c);
|
||||
list_counter++;
|
||||
obstack_ptr_grow (&vector_stack, read_nested_rtx ());
|
||||
}
|
||||
if (list_counter > 0)
|
||||
{
|
||||
return_vec = rtvec_alloc (list_counter);
|
||||
memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
|
||||
list_counter * sizeof (rtx));
|
||||
}
|
||||
else if (format_ptr[i] == 'E')
|
||||
fatal_with_file_and_line ("vector must have at least one element");
|
||||
XVEC (return_rtx, i) = return_vec;
|
||||
obstack_free (&vector_stack, NULL);
|
||||
/* close bracket gotten */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 's':
|
||||
{
|
||||
char *stringbuf;
|
||||
int star_if_braced;
|
||||
|
||||
c = read_skip_spaces ();
|
||||
unread_char (c);
|
||||
if (c == ')')
|
||||
{
|
||||
/* 'S' fields are optional and should be NULL if no string
|
||||
was given. Also allow normal 's' and 'T' strings to be
|
||||
omitted, treating them in the same way as empty strings. */
|
||||
XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : "");
|
||||
break;
|
||||
}
|
||||
|
||||
/* The output template slot of a DEFINE_INSN,
|
||||
DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
|
||||
gets a star inserted as its first character, if it is
|
||||
written with a brace block instead of a string constant. */
|
||||
star_if_braced = (format_ptr[i] == 'T');
|
||||
|
||||
stringbuf = read_string (star_if_braced);
|
||||
|
||||
/* For insn patterns, we want to provide a default name
|
||||
based on the file and line, like "*foo.md:12", if the
|
||||
given name is blank. These are only for define_insn and
|
||||
define_insn_and_split, to aid debugging. */
|
||||
if (*stringbuf == '\0'
|
||||
&& i == 0
|
||||
&& (GET_CODE (return_rtx) == DEFINE_INSN
|
||||
|| GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
|
||||
{
|
||||
char line_name[20];
|
||||
const char *read_md_filename = rtx_reader_ptr->get_filename ();
|
||||
const char *fn = (read_md_filename ? read_md_filename : "rtx");
|
||||
const char *slash;
|
||||
for (slash = fn; *slash; slash ++)
|
||||
if (*slash == '/' || *slash == '\\' || *slash == ':')
|
||||
fn = slash + 1;
|
||||
obstack_1grow (&string_obstack, '*');
|
||||
obstack_grow (&string_obstack, fn, strlen (fn));
|
||||
sprintf (line_name, ":%d", rtx_reader_ptr->get_lineno ());
|
||||
obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
|
||||
stringbuf = XOBFINISH (&string_obstack, char *);
|
||||
}
|
||||
|
||||
/* Find attr-names in the string. */
|
||||
ptr = &tmpstr[0];
|
||||
end = stringbuf;
|
||||
while ((start = strchr (end, '<')) && (end = strchr (start, '>')))
|
||||
{
|
||||
if ((end - start - 1 > 0)
|
||||
&& (end - start - 1 < (int)sizeof (tmpstr)))
|
||||
{
|
||||
strncpy (tmpstr, start+1, end-start-1);
|
||||
tmpstr[end-start-1] = 0;
|
||||
end++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
m = (struct mapping *) htab_find (substs.attrs, &ptr);
|
||||
if (m != 0)
|
||||
{
|
||||
/* Here we should find linked subst-iter. */
|
||||
str = find_subst_iter_by_attr (ptr);
|
||||
if (str)
|
||||
m = (struct mapping *) htab_find (substs.iterators, &str);
|
||||
else
|
||||
m = 0;
|
||||
}
|
||||
if (m != 0)
|
||||
record_iterator_use (m, return_rtx);
|
||||
}
|
||||
|
||||
if (star_if_braced)
|
||||
XTMPL (return_rtx, i) = stringbuf;
|
||||
else
|
||||
XSTR (return_rtx, i) = stringbuf;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
read_name (&name);
|
||||
validate_const_int (name.string);
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
|
||||
tmp_wide = atoi (name.string);
|
||||
#else
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
tmp_wide = atol (name.string);
|
||||
#else
|
||||
/* Prefer atoll over atoq, since the former is in the ISO C99 standard.
|
||||
But prefer not to use our hand-rolled function above either. */
|
||||
#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
|
||||
tmp_wide = atoll (name.string);
|
||||
#else
|
||||
tmp_wide = atoq (name.string);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
XWINT (return_rtx, i) = tmp_wide;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'n':
|
||||
/* Can be an iterator or an integer constant. */
|
||||
read_name (&name);
|
||||
record_potential_iterator_use (&ints, &XINT (return_rtx, i),
|
||||
name.string);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
read_name (&name);
|
||||
validate_const_int (name.string);
|
||||
set_regno_raw (return_rtx, atoi (name.string), 1);
|
||||
REG_ATTRS (return_rtx) = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
for (int idx = 0; format_ptr[idx] != 0; idx++)
|
||||
read_rtx_operand (return_rtx, idx);
|
||||
|
||||
if (CONST_WIDE_INT_P (return_rtx))
|
||||
{
|
||||
@ -1382,6 +1196,210 @@ read_rtx_code (const char *code_name)
|
||||
return return_rtx;
|
||||
}
|
||||
|
||||
/* Subroutine of read_rtx_code. Parse operand IDX within RETURN_RTX,
|
||||
based on the corresponding format character within GET_RTX_FORMAT
|
||||
for the GET_CODE (RETURN_RTX). */
|
||||
|
||||
static void
|
||||
read_rtx_operand (rtx return_rtx, int idx)
|
||||
{
|
||||
RTX_CODE code = GET_CODE (return_rtx);
|
||||
const char *format_ptr = GET_RTX_FORMAT (code);
|
||||
int c;
|
||||
struct md_name name;
|
||||
|
||||
switch (format_ptr[idx])
|
||||
{
|
||||
/* 0 means a field for internal use only.
|
||||
Don't expect it to be present in the input. */
|
||||
case '0':
|
||||
if (code == REG)
|
||||
ORIGINAL_REGNO (return_rtx) = REGNO (return_rtx);
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'u':
|
||||
XEXP (return_rtx, idx) = read_nested_rtx ();
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
/* 'V' is an optional vector: if a closeparen follows,
|
||||
just store NULL for this element. */
|
||||
c = read_skip_spaces ();
|
||||
unread_char (c);
|
||||
if (c == ')')
|
||||
{
|
||||
XVEC (return_rtx, idx) = 0;
|
||||
break;
|
||||
}
|
||||
/* Now process the vector. */
|
||||
/* FALLTHRU */
|
||||
|
||||
case 'E':
|
||||
{
|
||||
/* Obstack to store scratch vector in. */
|
||||
struct obstack vector_stack;
|
||||
int list_counter = 0;
|
||||
rtvec return_vec = NULL_RTVEC;
|
||||
|
||||
require_char_ws ('[');
|
||||
|
||||
/* Add expressions to a list, while keeping a count. */
|
||||
obstack_init (&vector_stack);
|
||||
while ((c = read_skip_spaces ()) && c != ']')
|
||||
{
|
||||
if (c == EOF)
|
||||
fatal_expected_char (']', c);
|
||||
unread_char (c);
|
||||
list_counter++;
|
||||
obstack_ptr_grow (&vector_stack, read_nested_rtx ());
|
||||
}
|
||||
if (list_counter > 0)
|
||||
{
|
||||
return_vec = rtvec_alloc (list_counter);
|
||||
memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
|
||||
list_counter * sizeof (rtx));
|
||||
}
|
||||
else if (format_ptr[idx] == 'E')
|
||||
fatal_with_file_and_line ("vector must have at least one element");
|
||||
XVEC (return_rtx, idx) = return_vec;
|
||||
obstack_free (&vector_stack, NULL);
|
||||
/* close bracket gotten */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'T':
|
||||
case 's':
|
||||
{
|
||||
char *stringbuf;
|
||||
int star_if_braced;
|
||||
|
||||
c = read_skip_spaces ();
|
||||
unread_char (c);
|
||||
if (c == ')')
|
||||
{
|
||||
/* 'S' fields are optional and should be NULL if no string
|
||||
was given. Also allow normal 's' and 'T' strings to be
|
||||
omitted, treating them in the same way as empty strings. */
|
||||
XSTR (return_rtx, idx) = (format_ptr[idx] == 'S' ? NULL : "");
|
||||
break;
|
||||
}
|
||||
|
||||
/* The output template slot of a DEFINE_INSN,
|
||||
DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
|
||||
gets a star inserted as its first character, if it is
|
||||
written with a brace block instead of a string constant. */
|
||||
star_if_braced = (format_ptr[idx] == 'T');
|
||||
|
||||
stringbuf = read_string (star_if_braced);
|
||||
|
||||
/* For insn patterns, we want to provide a default name
|
||||
based on the file and line, like "*foo.md:12", if the
|
||||
given name is blank. These are only for define_insn and
|
||||
define_insn_and_split, to aid debugging. */
|
||||
if (*stringbuf == '\0'
|
||||
&& idx == 0
|
||||
&& (GET_CODE (return_rtx) == DEFINE_INSN
|
||||
|| GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
|
||||
{
|
||||
char line_name[20];
|
||||
const char *read_md_filename = rtx_reader_ptr->get_filename ();
|
||||
const char *fn = (read_md_filename ? read_md_filename : "rtx");
|
||||
const char *slash;
|
||||
for (slash = fn; *slash; slash ++)
|
||||
if (*slash == '/' || *slash == '\\' || *slash == ':')
|
||||
fn = slash + 1;
|
||||
obstack_1grow (&string_obstack, '*');
|
||||
obstack_grow (&string_obstack, fn, strlen (fn));
|
||||
sprintf (line_name, ":%d", rtx_reader_ptr->get_lineno ());
|
||||
obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
|
||||
stringbuf = XOBFINISH (&string_obstack, char *);
|
||||
}
|
||||
|
||||
/* Find attr-names in the string. */
|
||||
char *str;
|
||||
char *start, *end, *ptr;
|
||||
char tmpstr[256];
|
||||
ptr = &tmpstr[0];
|
||||
end = stringbuf;
|
||||
while ((start = strchr (end, '<')) && (end = strchr (start, '>')))
|
||||
{
|
||||
if ((end - start - 1 > 0)
|
||||
&& (end - start - 1 < (int)sizeof (tmpstr)))
|
||||
{
|
||||
strncpy (tmpstr, start+1, end-start-1);
|
||||
tmpstr[end-start-1] = 0;
|
||||
end++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
struct mapping *m
|
||||
= (struct mapping *) htab_find (substs.attrs, &ptr);
|
||||
if (m != 0)
|
||||
{
|
||||
/* Here we should find linked subst-iter. */
|
||||
str = find_subst_iter_by_attr (ptr);
|
||||
if (str)
|
||||
m = (struct mapping *) htab_find (substs.iterators, &str);
|
||||
else
|
||||
m = 0;
|
||||
}
|
||||
if (m != 0)
|
||||
record_iterator_use (m, return_rtx);
|
||||
}
|
||||
|
||||
if (star_if_braced)
|
||||
XTMPL (return_rtx, idx) = stringbuf;
|
||||
else
|
||||
XSTR (return_rtx, idx) = stringbuf;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
{
|
||||
HOST_WIDE_INT tmp_wide;
|
||||
read_name (&name);
|
||||
validate_const_int (name.string);
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
|
||||
tmp_wide = atoi (name.string);
|
||||
#else
|
||||
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
|
||||
tmp_wide = atol (name.string);
|
||||
#else
|
||||
/* Prefer atoll over atoq, since the former is in the ISO C99 standard.
|
||||
But prefer not to use our hand-rolled function above either. */
|
||||
#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
|
||||
tmp_wide = atoll (name.string);
|
||||
#else
|
||||
tmp_wide = atoq (name.string);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
XWINT (return_rtx, idx) = tmp_wide;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'n':
|
||||
/* Can be an iterator or an integer constant. */
|
||||
read_name (&name);
|
||||
record_potential_iterator_use (&ints, &XINT (return_rtx, idx),
|
||||
name.string);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
read_name (&name);
|
||||
validate_const_int (name.string);
|
||||
set_regno_raw (return_rtx, atoi (name.string), 1);
|
||||
REG_ATTRS (return_rtx) = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a nested rtx construct from the MD file and return it. */
|
||||
|
||||
static rtx
|
||||
|
Loading…
Reference in New Issue
Block a user