OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [genflags.c] - Diff between revs 154 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
/* Generate from machine description:
/* Generate from machine description:
   - some flags HAVE_... saying which simple standard instructions are
   - some flags HAVE_... saying which simple standard instructions are
   available for this machine.
   available for this machine.
   Copyright (C) 1987, 1991, 1995, 1998, 1999, 2000, 2003, 2004, 2007
   Copyright (C) 1987, 1991, 1995, 1998, 1999, 2000, 2003, 2004, 2007
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify it under
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
Software Foundation; either version 3, or (at your option) any later
version.
version.
 
 
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
 
 
#include "bconfig.h"
#include "bconfig.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "rtl.h"
#include "rtl.h"
#include "obstack.h"
#include "obstack.h"
#include "errors.h"
#include "errors.h"
#include "gensupport.h"
#include "gensupport.h"
 
 
/* Obstack to remember insns with.  */
/* Obstack to remember insns with.  */
static struct obstack obstack;
static struct obstack obstack;
 
 
/* Max size of names encountered.  */
/* Max size of names encountered.  */
static int max_id_len;
static int max_id_len;
 
 
/* Max operand encountered in a scan over some insn.  */
/* Max operand encountered in a scan over some insn.  */
static int max_opno;
static int max_opno;
 
 
static void max_operand_1 (rtx);
static void max_operand_1 (rtx);
static int num_operands (rtx);
static int num_operands (rtx);
static void gen_proto (rtx);
static void gen_proto (rtx);
static void gen_macro (const char *, int, int);
static void gen_macro (const char *, int, int);
static void gen_insn (rtx);
static void gen_insn (rtx);
 
 
/* Count the number of match_operand's found.  */
/* Count the number of match_operand's found.  */
 
 
static void
static void
max_operand_1 (rtx x)
max_operand_1 (rtx x)
{
{
  RTX_CODE code;
  RTX_CODE code;
  int i;
  int i;
  int len;
  int len;
  const char *fmt;
  const char *fmt;
 
 
  if (x == 0)
  if (x == 0)
    return;
    return;
 
 
  code = GET_CODE (x);
  code = GET_CODE (x);
 
 
  if (code == MATCH_OPERAND || code == MATCH_OPERATOR
  if (code == MATCH_OPERAND || code == MATCH_OPERATOR
      || code == MATCH_PARALLEL)
      || code == MATCH_PARALLEL)
    max_opno = MAX (max_opno, XINT (x, 0));
    max_opno = MAX (max_opno, XINT (x, 0));
 
 
  fmt = GET_RTX_FORMAT (code);
  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
  for (i = 0; i < len; i++)
    {
    {
      if (fmt[i] == 'e' || fmt[i] == 'u')
      if (fmt[i] == 'e' || fmt[i] == 'u')
        max_operand_1 (XEXP (x, i));
        max_operand_1 (XEXP (x, i));
      else if (fmt[i] == 'E')
      else if (fmt[i] == 'E')
        {
        {
          int j;
          int j;
          for (j = 0; j < XVECLEN (x, i); j++)
          for (j = 0; j < XVECLEN (x, i); j++)
            max_operand_1 (XVECEXP (x, i, j));
            max_operand_1 (XVECEXP (x, i, j));
        }
        }
    }
    }
}
}
 
 
static int
static int
num_operands (rtx insn)
num_operands (rtx insn)
{
{
  int len = XVECLEN (insn, 1);
  int len = XVECLEN (insn, 1);
  int i;
  int i;
 
 
  max_opno = -1;
  max_opno = -1;
 
 
  for (i = 0; i < len; i++)
  for (i = 0; i < len; i++)
    max_operand_1 (XVECEXP (insn, 1, i));
    max_operand_1 (XVECEXP (insn, 1, i));
 
 
  return max_opno + 1;
  return max_opno + 1;
}
}
 
 
/* Print out a wrapper macro for a function which corrects the number
/* Print out a wrapper macro for a function which corrects the number
   of arguments it takes.  Any missing arguments are assumed to be at
   of arguments it takes.  Any missing arguments are assumed to be at
   the end.  */
   the end.  */
static void
static void
gen_macro (const char *name, int real, int expect)
gen_macro (const char *name, int real, int expect)
{
{
  int i;
  int i;
 
 
  gcc_assert (real <= expect);
  gcc_assert (real <= expect);
  gcc_assert (real);
  gcc_assert (real);
 
 
  /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
  /* #define GEN_CALL(A, B, C, D) gen_call((A), (B)) */
  fputs ("#define GEN_", stdout);
  fputs ("#define GEN_", stdout);
  for (i = 0; name[i]; i++)
  for (i = 0; name[i]; i++)
    putchar (TOUPPER (name[i]));
    putchar (TOUPPER (name[i]));
 
 
  putchar('(');
  putchar('(');
  for (i = 0; i < expect - 1; i++)
  for (i = 0; i < expect - 1; i++)
    printf ("%c, ", i + 'A');
    printf ("%c, ", i + 'A');
  printf ("%c) gen_%s (", i + 'A', name);
  printf ("%c) gen_%s (", i + 'A', name);
 
 
  for (i = 0; i < real - 1; i++)
  for (i = 0; i < real - 1; i++)
    printf ("(%c), ", i + 'A');
    printf ("(%c), ", i + 'A');
  printf ("(%c))\n", i + 'A');
  printf ("(%c))\n", i + 'A');
}
}
 
 
/* Print out prototype information for a generator function.  If the
/* Print out prototype information for a generator function.  If the
   insn pattern has been elided, print out a dummy generator that
   insn pattern has been elided, print out a dummy generator that
   does nothing.  */
   does nothing.  */
 
 
static void
static void
gen_proto (rtx insn)
gen_proto (rtx insn)
{
{
  int num = num_operands (insn);
  int num = num_operands (insn);
  int i;
  int i;
  const char *name = XSTR (insn, 0);
  const char *name = XSTR (insn, 0);
  int truth = maybe_eval_c_test (XSTR (insn, 2));
  int truth = maybe_eval_c_test (XSTR (insn, 2));
 
 
  /* Many md files don't refer to the last two operands passed to the
  /* Many md files don't refer to the last two operands passed to the
     call patterns.  This means their generator functions will be two
     call patterns.  This means their generator functions will be two
     arguments too short.  Instead of changing every md file to touch
     arguments too short.  Instead of changing every md file to touch
     those operands, we wrap the prototypes in macros that take the
     those operands, we wrap the prototypes in macros that take the
     correct number of arguments.  */
     correct number of arguments.  */
  if (name[0] == 'c' || name[0] == 's')
  if (name[0] == 'c' || name[0] == 's')
    {
    {
      if (!strcmp (name, "call")
      if (!strcmp (name, "call")
          || !strcmp (name, "call_pop")
          || !strcmp (name, "call_pop")
          || !strcmp (name, "sibcall")
          || !strcmp (name, "sibcall")
          || !strcmp (name, "sibcall_pop"))
          || !strcmp (name, "sibcall_pop"))
        gen_macro (name, num, 4);
        gen_macro (name, num, 4);
      else if (!strcmp (name, "call_value")
      else if (!strcmp (name, "call_value")
               || !strcmp (name, "call_value_pop")
               || !strcmp (name, "call_value_pop")
               || !strcmp (name, "sibcall_value")
               || !strcmp (name, "sibcall_value")
               || !strcmp (name, "sibcall_value_pop"))
               || !strcmp (name, "sibcall_value_pop"))
        gen_macro (name, num, 5);
        gen_macro (name, num, 5);
    }
    }
 
 
  if (truth != 0)
  if (truth != 0)
    printf ("extern rtx        gen_%-*s (", max_id_len, name);
    printf ("extern rtx        gen_%-*s (", max_id_len, name);
  else
  else
    printf ("static inline rtx gen_%-*s (", max_id_len, name);
    printf ("static inline rtx gen_%-*s (", max_id_len, name);
 
 
  if (num == 0)
  if (num == 0)
    fputs ("void", stdout);
    fputs ("void", stdout);
  else
  else
    {
    {
      for (i = 1; i < num; i++)
      for (i = 1; i < num; i++)
        fputs ("rtx, ", stdout);
        fputs ("rtx, ", stdout);
 
 
      fputs ("rtx", stdout);
      fputs ("rtx", stdout);
    }
    }
 
 
  puts (");");
  puts (");");
 
 
  /* Some back ends want to take the address of generator functions,
  /* Some back ends want to take the address of generator functions,
     so we cannot simply use #define for these dummy definitions.  */
     so we cannot simply use #define for these dummy definitions.  */
  if (truth == 0)
  if (truth == 0)
    {
    {
      printf ("static inline rtx\ngen_%s", name);
      printf ("static inline rtx\ngen_%s", name);
      if (num > 0)
      if (num > 0)
        {
        {
          putchar ('(');
          putchar ('(');
          for (i = 0; i < num-1; i++)
          for (i = 0; i < num-1; i++)
            printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
            printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
          printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
          printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
        }
        }
      else
      else
        puts ("(void)");
        puts ("(void)");
      puts ("{\n  return 0;\n}");
      puts ("{\n  return 0;\n}");
    }
    }
 
 
}
}
 
 
static void
static void
gen_insn (rtx insn)
gen_insn (rtx insn)
{
{
  const char *name = XSTR (insn, 0);
  const char *name = XSTR (insn, 0);
  const char *p;
  const char *p;
  int len;
  int len;
  int truth = maybe_eval_c_test (XSTR (insn, 2));
  int truth = maybe_eval_c_test (XSTR (insn, 2));
 
 
  /* Don't mention instructions whose names are the null string
  /* Don't mention instructions whose names are the null string
     or begin with '*'.  They are in the machine description just
     or begin with '*'.  They are in the machine description just
     to be recognized.  */
     to be recognized.  */
  if (name[0] == 0 || name[0] == '*')
  if (name[0] == 0 || name[0] == '*')
    return;
    return;
 
 
  len = strlen (name);
  len = strlen (name);
 
 
  if (len > max_id_len)
  if (len > max_id_len)
    max_id_len = len;
    max_id_len = len;
 
 
  if (truth == 0)
  if (truth == 0)
    /* Emit nothing.  */;
    /* Emit nothing.  */;
  else if (truth == 1)
  else if (truth == 1)
    printf ("#define HAVE_%s 1\n", name);
    printf ("#define HAVE_%s 1\n", name);
  else
  else
    {
    {
      /* Write the macro definition, putting \'s at the end of each line,
      /* Write the macro definition, putting \'s at the end of each line,
         if more than one.  */
         if more than one.  */
      printf ("#define HAVE_%s (", name);
      printf ("#define HAVE_%s (", name);
      for (p = XSTR (insn, 2); *p; p++)
      for (p = XSTR (insn, 2); *p; p++)
        {
        {
          if (IS_VSPACE (*p))
          if (IS_VSPACE (*p))
            fputs (" \\\n", stdout);
            fputs (" \\\n", stdout);
          else
          else
            putchar (*p);
            putchar (*p);
        }
        }
      fputs (")\n", stdout);
      fputs (")\n", stdout);
    }
    }
 
 
  obstack_grow (&obstack, &insn, sizeof (rtx));
  obstack_grow (&obstack, &insn, sizeof (rtx));
}
}
 
 
int
int
main (int argc, char **argv)
main (int argc, char **argv)
{
{
  rtx desc;
  rtx desc;
  rtx dummy;
  rtx dummy;
  rtx *insns;
  rtx *insns;
  rtx *insn_ptr;
  rtx *insn_ptr;
 
 
  progname = "genflags";
  progname = "genflags";
  obstack_init (&obstack);
  obstack_init (&obstack);
 
 
  /* We need to see all the possibilities.  Elided insns may have
  /* We need to see all the possibilities.  Elided insns may have
     direct calls to their generators in C code.  */
     direct calls to their generators in C code.  */
  insn_elision = 0;
  insn_elision = 0;
 
 
  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
    return (FATAL_EXIT_CODE);
    return (FATAL_EXIT_CODE);
 
 
  puts ("/* Generated automatically by the program `genflags'");
  puts ("/* Generated automatically by the program `genflags'");
  puts ("   from the machine description file `md'.  */\n");
  puts ("   from the machine description file `md'.  */\n");
  puts ("#ifndef GCC_INSN_FLAGS_H");
  puts ("#ifndef GCC_INSN_FLAGS_H");
  puts ("#define GCC_INSN_FLAGS_H\n");
  puts ("#define GCC_INSN_FLAGS_H\n");
 
 
  /* Read the machine description.  */
  /* Read the machine description.  */
 
 
  while (1)
  while (1)
    {
    {
      int line_no, insn_code_number = 0;
      int line_no, insn_code_number = 0;
 
 
      desc = read_md_rtx (&line_no, &insn_code_number);
      desc = read_md_rtx (&line_no, &insn_code_number);
      if (desc == NULL)
      if (desc == NULL)
        break;
        break;
      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
        gen_insn (desc);
        gen_insn (desc);
    }
    }
 
 
  /* Print out the prototypes now.  */
  /* Print out the prototypes now.  */
  dummy = (rtx) 0;
  dummy = (rtx) 0;
  obstack_grow (&obstack, &dummy, sizeof (rtx));
  obstack_grow (&obstack, &dummy, sizeof (rtx));
  insns = XOBFINISH (&obstack, rtx *);
  insns = XOBFINISH (&obstack, rtx *);
 
 
  for (insn_ptr = insns; *insn_ptr; insn_ptr++)
  for (insn_ptr = insns; *insn_ptr; insn_ptr++)
    gen_proto (*insn_ptr);
    gen_proto (*insn_ptr);
 
 
  puts("\n#endif /* GCC_INSN_FLAGS_H */");
  puts("\n#endif /* GCC_INSN_FLAGS_H */");
 
 
  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
    return FATAL_EXIT_CODE;
    return FATAL_EXIT_CODE;
 
 
  return SUCCESS_EXIT_CODE;
  return SUCCESS_EXIT_CODE;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.