#include "hconfig.h"
#include "system.h"
#include "rtl.h"
#include "obstack.h"
static struct obstack obstack;
struct obstack *rtl_obstack = &obstack;
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
void fatal PVPROTO ((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
char **insn_name_ptr;
static struct obstack call_obstack, normal_obstack;
static int max_id_len;
static int num_operands PROTO((rtx));
static void gen_proto PROTO((rtx));
static void gen_nonproto PROTO((rtx));
static void gen_insn PROTO((rtx));
static int
num_operands (x)
rtx x;
{
int count = 0;
int i, j;
enum rtx_code code = GET_CODE (x);
char *format_ptr = GET_RTX_FORMAT (code);
if (code == MATCH_OPERAND)
return 1;
if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
count++;
for (i = 0; i < GET_RTX_LENGTH (code); i++)
{
switch (*format_ptr++)
{
case 'u':
case 'e':
count += num_operands (XEXP (x, i));
break;
case 'E':
if (XVEC (x, i) != NULL)
for (j = 0; j < XVECLEN (x, i); j++)
count += num_operands (XVECEXP (x, i, j));
break;
}
}
return count;
}
static void
gen_proto (insn)
rtx insn;
{
int num = num_operands (insn);
printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));
if (num == 0)
printf ("void");
else
{
while (num-- > 1)
printf ("rtx, ");
printf ("rtx");
}
printf ("));\n");
}
static void
gen_nonproto (insn)
rtx insn;
{
printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
}
static void
gen_insn (insn)
rtx insn;
{
char *name = XSTR (insn, 0);
char *p;
struct obstack *obstack_ptr;
int len;
if (name[0] == 0 || name[0] == '*')
return;
len = strlen (name);
if (len > max_id_len)
max_id_len = len;
printf ("#define HAVE_%s ", name);
if (strlen (XSTR (insn, 2)) == 0)
printf ("1\n");
else
{
printf ("(");
for (p = XSTR (insn, 2); *p; p++)
{
if (*p == '\n')
printf (" \\\n");
else
printf ("%c", *p);
}
printf (")\n");
}
obstack_ptr = (name[0] == 'c'
&& (!strcmp (name, "call")
|| !strcmp (name, "call_value")
|| !strcmp (name, "call_pop")
|| !strcmp (name, "call_value_pop")))
? &call_obstack : &normal_obstack;
obstack_grow (obstack_ptr, &insn, sizeof (rtx));
}
PTR
xmalloc (size)
size_t size;
{
register PTR val = (PTR) malloc (size);
if (val == 0)
fatal ("virtual memory exhausted");
return val;
}
PTR
xrealloc (old, size)
PTR old;
size_t size;
{
register PTR ptr;
if (old)
ptr = (PTR) realloc (old, size);
else
ptr = (PTR) malloc (size);
if (!ptr)
fatal ("virtual memory exhausted");
return ptr;
}
void
fatal VPROTO ((const char *format, ...))
{
#ifndef ANSI_PROTOTYPES
const char *format;
#endif
va_list ap;
VA_START (ap, format);
#ifndef ANSI_PROTOTYPES
format = va_arg (ap, const char *);
#endif
fprintf (stderr, "genflags: ");
vfprintf (stderr, format, ap);
va_end (ap);
fprintf (stderr, "\n");
exit (FATAL_EXIT_CODE);
}
void
fancy_abort ()
{
fatal ("Internal gcc abort.");
}
int
main (argc, argv)
int argc;
char **argv;
{
rtx desc;
rtx dummy;
rtx *call_insns;
rtx *normal_insns;
rtx *insn_ptr;
FILE *infile;
register int c;
obstack_init (rtl_obstack);
obstack_init (&call_obstack);
obstack_init (&normal_obstack);
if (argc <= 1)
fatal ("No input file name.");
infile = fopen (argv[1], "r");
if (infile == 0)
{
perror (argv[1]);
exit (FATAL_EXIT_CODE);
}
init_rtl ();
printf ("/* Generated automatically by the program `genflags'\n\
from the machine description file `md'. */\n\n");
while (1)
{
c = read_skip_spaces (infile);
if (c == EOF)
break;
ungetc (c, infile);
desc = read_rtx (infile);
if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
gen_insn (desc);
}
dummy = (rtx) 0;
obstack_grow (&call_obstack, &dummy, sizeof (rtx));
call_insns = (rtx *) obstack_finish (&call_obstack);
obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
normal_insns = (rtx *) obstack_finish (&normal_obstack);
printf ("\n#ifndef NO_MD_PROTOTYPES\n");
for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
gen_proto (*insn_ptr);
printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
gen_proto (*insn_ptr);
printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
gen_nonproto (*insn_ptr);
printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
printf ("\n#else /* NO_MD_PROTOTYPES */\n");
for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
gen_nonproto (*insn_ptr);
for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
gen_nonproto (*insn_ptr);
printf ("#endif /* NO_MD_PROTOTYPES */\n");
fflush (stdout);
exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
return 0;
}