#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
static int max_recog_operands;
static int max_dup_operands;
static int max_clobbers_per_insn;
static int have_cc0_flag;
static int have_cmove_flag;
static int have_cond_exec_flag;
static int have_lo_sum_flag;
static int have_peephole_flag;
static int have_peephole2_flag;
static int max_insns_per_split = 1;
static int max_insns_per_peep2;
static int clobbers_seen_this_insn;
static int dup_operands_seen_this_insn;
static void walk_insn_part (rtx, int, int);
static void gen_insn (rtx);
static void gen_expand (rtx);
static void gen_split (rtx);
static void gen_peephole (rtx);
static void gen_peephole2 (rtx);
static void
walk_insn_part (rtx part, int recog_p, int non_pc_set_src)
{
int i, j;
RTX_CODE code;
const char *format_ptr;
if (part == 0)
return;
code = GET_CODE (part);
switch (code)
{
case CLOBBER:
clobbers_seen_this_insn++;
break;
case MATCH_OPERAND:
if (XINT (part, 0) > max_recog_operands)
max_recog_operands = XINT (part, 0);
return;
case MATCH_OP_DUP:
case MATCH_PAR_DUP:
++dup_operands_seen_this_insn;
case MATCH_SCRATCH:
case MATCH_PARALLEL:
case MATCH_OPERATOR:
if (XINT (part, 0) > max_recog_operands)
max_recog_operands = XINT (part, 0);
break;
case LABEL_REF:
if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND
|| GET_CODE (XEXP (part, 0)) == MATCH_DUP)
break;
return;
case MATCH_DUP:
++dup_operands_seen_this_insn;
if (XINT (part, 0) > max_recog_operands)
max_recog_operands = XINT (part, 0);
return;
case CC0:
if (recog_p)
have_cc0_flag = 1;
return;
case LO_SUM:
if (recog_p)
have_lo_sum_flag = 1;
return;
case SET:
walk_insn_part (SET_DEST (part), 0, recog_p);
walk_insn_part (SET_SRC (part), recog_p,
GET_CODE (SET_DEST (part)) != PC);
return;
case IF_THEN_ELSE:
if (recog_p && non_pc_set_src
&& GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
&& GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
have_cmove_flag = 1;
break;
case COND_EXEC:
if (recog_p)
have_cond_exec_flag = 1;
break;
case REG: case CONST_INT: case SYMBOL_REF:
case PC:
return;
default:
break;
}
format_ptr = GET_RTX_FORMAT (GET_CODE (part));
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
switch (*format_ptr++)
{
case 'e':
case 'u':
walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
break;
case 'E':
if (XVEC (part, i) != NULL)
for (j = 0; j < XVECLEN (part, i); j++)
walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
break;
}
}
static void
gen_insn (rtx insn)
{
int i;
clobbers_seen_this_insn = 0;
dup_operands_seen_this_insn = 0;
if (XVEC (insn, 1) != 0)
for (i = 0; i < XVECLEN (insn, 1); i++)
walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
if (clobbers_seen_this_insn > max_clobbers_per_insn)
max_clobbers_per_insn = clobbers_seen_this_insn;
if (dup_operands_seen_this_insn > max_dup_operands)
max_dup_operands = dup_operands_seen_this_insn;
}
static void
gen_expand (rtx insn)
{
int i;
if (XVEC (insn, 1) != 0)
for (i = 0; i < XVECLEN (insn, 1); i++)
{
clobbers_seen_this_insn = 0;
walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
if (clobbers_seen_this_insn > max_clobbers_per_insn)
max_clobbers_per_insn = clobbers_seen_this_insn;
}
}
static void
gen_split (rtx split)
{
int i;
for (i = 0; i < XVECLEN (split, 0); i++)
walk_insn_part (XVECEXP (split, 0, i), 1, 0);
if (XVECLEN (split, 2) > max_insns_per_split)
max_insns_per_split = XVECLEN (split, 2);
}
static void
gen_peephole (rtx peep)
{
int i;
for (i = 0; i < XVECLEN (peep, 0); i++)
walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
}
static void
gen_peephole2 (rtx peep)
{
int i, n;
for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i)
if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP
&& GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH)
n++;
if (n > max_insns_per_peep2)
max_insns_per_peep2 = n;
}
int
main (int argc, char **argv)
{
rtx desc;
progname = "genconfig";
if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
puts ("/* Generated automatically by the program `genconfig'");
puts (" from the machine description file `md'. */\n");
puts ("#ifndef GCC_INSN_CONFIG_H");
puts ("#define GCC_INSN_CONFIG_H\n");
max_recog_operands = 29;
max_dup_operands = 1;
while (1)
{
int line_no, insn_code_number = 0;
desc = read_md_rtx (&line_no, &insn_code_number);
if (desc == NULL)
break;
switch (GET_CODE (desc))
{
case DEFINE_INSN:
gen_insn (desc);
break;
case DEFINE_EXPAND:
gen_expand (desc);
break;
case DEFINE_SPLIT:
gen_split (desc);
break;
case DEFINE_PEEPHOLE2:
have_peephole2_flag = 1;
gen_peephole2 (desc);
break;
case DEFINE_PEEPHOLE:
have_peephole_flag = 1;
gen_peephole (desc);
break;
default:
break;
}
}
printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
printf ("#endif\n");
if (have_cc0_flag)
{
printf ("#define HAVE_cc0 1\n");
printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");
}
else
{
printf ("#define CC0_P(X) ((X) ? 0 : 0)\n");
}
if (have_cmove_flag)
printf ("#define HAVE_conditional_move 1\n");
if (have_cond_exec_flag)
printf ("#define HAVE_conditional_execution 1\n");
if (have_lo_sum_flag)
printf ("#define HAVE_lo_sum 1\n");
if (have_peephole_flag)
printf ("#define HAVE_peephole 1\n");
if (have_peephole2_flag)
{
printf ("#define HAVE_peephole2 1\n");
printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2);
}
puts("\n#endif /* GCC_INSN_CONFIG_H */");
if (ferror (stdout) || fflush (stdout) || fclose (stdout))
return FATAL_EXIT_CODE;
return SUCCESS_EXIT_CODE;
}
const char *
get_insn_name (int ARG_UNUSED (code))
{
return NULL;
}