Home | History | Annotate | Line # | Download | only in gcc
gengenrtl.cc revision 1.1
      1  1.1  mrg /* Generate code to allocate RTL structures.
      2  1.1  mrg    Copyright (C) 1997-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg This file is part of GCC.
      5  1.1  mrg 
      6  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      7  1.1  mrg the terms of the GNU General Public License as published by the Free
      8  1.1  mrg Software Foundation; either version 3, or (at your option) any later
      9  1.1  mrg version.
     10  1.1  mrg 
     11  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     12  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  1.1  mrg for more details.
     15  1.1  mrg 
     16  1.1  mrg You should have received a copy of the GNU General Public License
     17  1.1  mrg along with GCC; see the file COPYING3.  If not see
     18  1.1  mrg <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg 
     21  1.1  mrg #include "bconfig.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg 
     24  1.1  mrg struct rtx_definition
     25  1.1  mrg {
     26  1.1  mrg   const char *const enumname, *const name, *const format;
     27  1.1  mrg };
     28  1.1  mrg 
     29  1.1  mrg /* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
     30  1.1  mrg    CONST_DOUBLE_FORMAT is because we're not going to be generating
     31  1.1  mrg    anything for CONST_DOUBLE anyway.  */
     32  1.1  mrg #define CONST_DOUBLE_FORMAT ""
     33  1.1  mrg 
     34  1.1  mrg #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
     35  1.1  mrg 
     36  1.1  mrg static const struct rtx_definition defs[] =
     37  1.1  mrg {
     38  1.1  mrg #include "rtl.def"		/* rtl expressions are documented here */
     39  1.1  mrg };
     40  1.1  mrg #define NUM_RTX_CODE ARRAY_SIZE (defs)
     41  1.1  mrg 
     42  1.1  mrg static const char *formats[NUM_RTX_CODE];
     43  1.1  mrg 
     44  1.1  mrg /* Decode a format letter into a C type string.  */
     46  1.1  mrg 
     47  1.1  mrg static const char *
     48  1.1  mrg type_from_format (int c)
     49  1.1  mrg {
     50  1.1  mrg   switch (c)
     51  1.1  mrg     {
     52  1.1  mrg     case 'i':
     53  1.1  mrg       return "int ";
     54  1.1  mrg 
     55  1.1  mrg     case 'w':
     56  1.1  mrg       return "HOST_WIDE_INT ";
     57  1.1  mrg 
     58  1.1  mrg     case 'p':
     59  1.1  mrg       return "poly_uint16 ";
     60  1.1  mrg 
     61  1.1  mrg     case 's':
     62  1.1  mrg       return "const char *";
     63  1.1  mrg 
     64  1.1  mrg     case 'e':  case 'u':
     65  1.1  mrg       return "rtx ";
     66  1.1  mrg 
     67  1.1  mrg     case 'E':
     68  1.1  mrg       return "rtvec ";
     69  1.1  mrg     case 't':
     70  1.1  mrg       return "tree ";
     71  1.1  mrg     case 'B':
     72  1.1  mrg       return "basic_block ";
     73  1.1  mrg     default:
     74  1.1  mrg       gcc_unreachable ();
     75  1.1  mrg     }
     76  1.1  mrg }
     77  1.1  mrg 
     78  1.1  mrg /* Decode a format letter into the proper accessor function.  */
     79  1.1  mrg 
     80  1.1  mrg static const char *
     81  1.1  mrg accessor_from_format (int c)
     82  1.1  mrg {
     83  1.1  mrg   switch (c)
     84  1.1  mrg     {
     85  1.1  mrg     case 'i':
     86  1.1  mrg       return "XINT";
     87  1.1  mrg 
     88  1.1  mrg     case 'w':
     89  1.1  mrg       return "XWINT";
     90  1.1  mrg 
     91  1.1  mrg     case 's':
     92  1.1  mrg       return "XSTR";
     93  1.1  mrg 
     94  1.1  mrg     case 'e':  case 'u':
     95  1.1  mrg       return "XEXP";
     96  1.1  mrg 
     97  1.1  mrg     case 'E':
     98  1.1  mrg       return "XVEC";
     99  1.1  mrg 
    100  1.1  mrg     case 't':
    101  1.1  mrg       return "XTREE";
    102  1.1  mrg 
    103  1.1  mrg     case 'B':
    104  1.1  mrg       return "XBBDEF";
    105  1.1  mrg 
    106  1.1  mrg     default:
    107  1.1  mrg       gcc_unreachable ();
    108  1.1  mrg     }
    109  1.1  mrg }
    110  1.1  mrg 
    111  1.1  mrg /* Return nonzero if we should ignore FMT, an RTL format, when making
    112  1.1  mrg    the list of formats we write routines to create.  */
    113  1.1  mrg 
    114  1.1  mrg static int
    115  1.1  mrg special_format (const char *fmt)
    116  1.1  mrg {
    117  1.1  mrg   return (strchr (fmt, '*') != 0
    118  1.1  mrg 	  || strchr (fmt, 'V') != 0
    119  1.1  mrg 	  || strchr (fmt, 'S') != 0
    120  1.1  mrg 	  || strchr (fmt, 'n') != 0
    121  1.1  mrg 	  || strchr (fmt, 'r') != 0);
    122  1.1  mrg }
    123  1.1  mrg 
    124  1.1  mrg /* Return true if CODE always has VOIDmode.  */
    125  1.1  mrg 
    126  1.1  mrg static inline bool
    127  1.1  mrg always_void_p (int idx)
    128  1.1  mrg {
    129  1.1  mrg   return strcmp (defs[idx].enumname, "SET") == 0;
    130  1.1  mrg }
    131  1.1  mrg 
    132  1.1  mrg /* Return nonzero if the RTL code given by index IDX is one that we should
    133  1.1  mrg    generate a gen_rtx_raw_FOO macro for, not gen_rtx_FOO (because gen_rtx_FOO
    134  1.1  mrg    is a wrapper in emit-rtl.cc).  */
    135  1.1  mrg 
    136  1.1  mrg static int
    137  1.1  mrg special_rtx (int idx)
    138  1.1  mrg {
    139  1.1  mrg   return (strcmp (defs[idx].enumname, "EXPR_LIST") == 0
    140  1.1  mrg 	  || strcmp (defs[idx].enumname, "INSN_LIST") == 0
    141  1.1  mrg 	  || strcmp (defs[idx].enumname, "INSN") == 0
    142  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_INT") == 0
    143  1.1  mrg 	  || strcmp (defs[idx].enumname, "REG") == 0
    144  1.1  mrg 	  || strcmp (defs[idx].enumname, "SUBREG") == 0
    145  1.1  mrg 	  || strcmp (defs[idx].enumname, "MEM") == 0
    146  1.1  mrg 	  || strcmp (defs[idx].enumname, "PC") == 0
    147  1.1  mrg 	  || strcmp (defs[idx].enumname, "RETURN") == 0
    148  1.1  mrg 	  || strcmp (defs[idx].enumname, "SIMPLE_RETURN") == 0
    149  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0);
    150  1.1  mrg }
    151  1.1  mrg 
    152  1.1  mrg /* Return nonzero if the RTL code given by index IDX is one that we should
    153  1.1  mrg    generate no macro for at all (because gen_rtx_FOO is never used or
    154  1.1  mrg    cannot have the obvious interface).  */
    155  1.1  mrg 
    156  1.1  mrg static int
    157  1.1  mrg excluded_rtx (int idx)
    158  1.1  mrg {
    159  1.1  mrg   return (strcmp (defs[idx].enumname, "VAR_LOCATION") == 0
    160  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
    161  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_WIDE_INT") == 0
    162  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_POLY_INT") == 0
    163  1.1  mrg 	  || strcmp (defs[idx].enumname, "CONST_FIXED") == 0);
    164  1.1  mrg }
    165  1.1  mrg 
    166  1.1  mrg /* Place a list of all format specifiers we use into the array FORMAT.  */
    167  1.1  mrg 
    168  1.1  mrg static void
    169  1.1  mrg find_formats (void)
    170  1.1  mrg {
    171  1.1  mrg   unsigned int i;
    172  1.1  mrg 
    173  1.1  mrg   for (i = 0; i < NUM_RTX_CODE; i++)
    174  1.1  mrg     {
    175  1.1  mrg       const char **f;
    176  1.1  mrg 
    177  1.1  mrg       if (special_format (defs[i].format))
    178  1.1  mrg 	continue;
    179  1.1  mrg 
    180  1.1  mrg       for (f = formats; *f; f++)
    181  1.1  mrg 	if (! strcmp (*f, defs[i].format))
    182  1.1  mrg 	  break;
    183  1.1  mrg 
    184  1.1  mrg       if (*f == 0)
    185  1.1  mrg 	*f = defs[i].format;
    186  1.1  mrg     }
    187  1.1  mrg }
    188  1.1  mrg 
    189  1.1  mrg 
    190  1.1  mrg /* Generate macros to generate RTL of code IDX using the functions we
    191  1.1  mrg    write.  */
    192  1.1  mrg 
    193  1.1  mrg static void
    194  1.1  mrg genmacro (int idx)
    195  1.1  mrg {
    196  1.1  mrg   const char *p;
    197  1.1  mrg   const char *sep = "";
    198  1.1  mrg   int i;
    199  1.1  mrg 
    200  1.1  mrg   /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
    201  1.1  mrg      gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE.  */
    202  1.1  mrg 
    203  1.1  mrg   if (excluded_rtx (idx))
    204  1.1  mrg     /* Don't define a macro for this code.  */
    205  1.1  mrg     return;
    206  1.1  mrg 
    207  1.1  mrg   bool has_mode_p = !always_void_p (idx);
    208  1.1  mrg   printf ("#define gen_rtx_%s%s(",
    209  1.1  mrg 	   special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
    210  1.1  mrg   if (has_mode_p)
    211  1.1  mrg     {
    212  1.1  mrg       printf ("MODE");
    213  1.1  mrg       sep = ", ";
    214  1.1  mrg     }
    215  1.1  mrg 
    216  1.1  mrg   for (p = defs[idx].format, i = 0; *p != 0; p++)
    217  1.1  mrg     if (*p != '0')
    218  1.1  mrg       {
    219  1.1  mrg 	printf ("%sARG%d", sep, i++);
    220  1.1  mrg 	sep = ", ";
    221  1.1  mrg       }
    222  1.1  mrg 
    223  1.1  mrg   printf (") \\\n  gen_rtx_fmt_%s (%s, %s",
    224  1.1  mrg 	  defs[idx].format, defs[idx].enumname,
    225  1.1  mrg 	  has_mode_p ? "(MODE)" : "VOIDmode");
    226  1.1  mrg 
    227  1.1  mrg   for (p = defs[idx].format, i = 0; *p != 0; p++)
    228  1.1  mrg     if (*p != '0')
    229  1.1  mrg       printf (", (ARG%d)", i++);
    230  1.1  mrg 
    231  1.1  mrg   puts (")");
    232  1.1  mrg }
    233  1.1  mrg 
    234  1.1  mrg /* Generate the code for functions to generate RTL whose format is FORMAT.  */
    235  1.1  mrg 
    236  1.1  mrg static void
    237  1.1  mrg gendef (const char *format)
    238  1.1  mrg {
    239  1.1  mrg   const char *p;
    240  1.1  mrg   int i, j;
    241  1.1  mrg 
    242  1.1  mrg   /* Write the definition of the init function name and the types
    243  1.1  mrg      of the arguments.  */
    244  1.1  mrg 
    245  1.1  mrg   puts ("static inline rtx");
    246  1.1  mrg   printf ("init_rtx_fmt_%s (rtx rt, machine_mode mode", format);
    247  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    248  1.1  mrg     if (*p != '0')
    249  1.1  mrg       printf (",\n\t%sarg%d", type_from_format (*p), i++);
    250  1.1  mrg   puts (")");
    251  1.1  mrg 
    252  1.1  mrg   /* Now write out the body of the init function itself.  */
    253  1.1  mrg   puts ("{");
    254  1.1  mrg   puts ("  PUT_MODE_RAW (rt, mode);");
    255  1.1  mrg 
    256  1.1  mrg   for (p = format, i = j = 0; *p ; ++p, ++i)
    257  1.1  mrg     if (*p == '0')
    258  1.1  mrg       printf ("  X0EXP (rt, %d) = NULL_RTX;\n", i);
    259  1.1  mrg     else if (*p == 'p')
    260  1.1  mrg       printf ("  SUBREG_BYTE (rt) = arg%d;\n", j++);
    261  1.1  mrg     else
    262  1.1  mrg       printf ("  %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
    263  1.1  mrg 
    264  1.1  mrg   puts ("  return rt;\n}\n");
    265  1.1  mrg 
    266  1.1  mrg   /* Write the definition of the gen function name and the types
    267  1.1  mrg      of the arguments.  */
    268  1.1  mrg 
    269  1.1  mrg   puts ("static inline rtx");
    270  1.1  mrg   printf ("gen_rtx_fmt_%s_stat (RTX_CODE code, machine_mode mode", format);
    271  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    272  1.1  mrg     if (*p != '0')
    273  1.1  mrg       printf (",\n\t%sarg%d", type_from_format (*p), i++);
    274  1.1  mrg   puts (" MEM_STAT_DECL)");
    275  1.1  mrg 
    276  1.1  mrg   /* Now write out the body of the function itself, which allocates
    277  1.1  mrg      the memory and initializes it.  */
    278  1.1  mrg   puts ("{");
    279  1.1  mrg   puts ("  rtx rt;\n");
    280  1.1  mrg 
    281  1.1  mrg   puts ("  rt = rtx_alloc (code PASS_MEM_STAT);");
    282  1.1  mrg   printf ("  return init_rtx_fmt_%s (rt, mode", format);
    283  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    284  1.1  mrg     if (*p != '0')
    285  1.1  mrg       printf (", arg%d", i++);
    286  1.1  mrg   puts (");\n}\n");
    287  1.1  mrg 
    288  1.1  mrg   /* Write the definition of gen macro.  */
    289  1.1  mrg 
    290  1.1  mrg   printf ("#define gen_rtx_fmt_%s(c, m", format);
    291  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    292  1.1  mrg     if (*p != '0')
    293  1.1  mrg       printf (", arg%d", i++);
    294  1.1  mrg   printf (") \\\n  gen_rtx_fmt_%s_stat ((c), (m)", format);
    295  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    296  1.1  mrg     if (*p != '0')
    297  1.1  mrg       printf (", (arg%d)", i++);
    298  1.1  mrg   printf (" MEM_STAT_INFO)\n\n");
    299  1.1  mrg 
    300  1.1  mrg   /* Write the definition of alloca macro.  */
    301  1.1  mrg 
    302  1.1  mrg   printf ("#define alloca_rtx_fmt_%s(c, m", format);
    303  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    304  1.1  mrg     if (*p != '0')
    305  1.1  mrg       printf (", arg%d", i++);
    306  1.1  mrg   printf (") \\\n  init_rtx_fmt_%s (rtx_alloca ((c)), (m)", format);
    307  1.1  mrg   for (p = format, i = 0; *p != 0; p++)
    308  1.1  mrg     if (*p != '0')
    309  1.1  mrg       printf (", (arg%d)", i++);
    310  1.1  mrg   printf (")\n\n");
    311  1.1  mrg }
    312  1.1  mrg 
    313  1.1  mrg /* Generate the documentation header for files we write.  */
    314  1.1  mrg 
    315  1.1  mrg static void
    316  1.1  mrg genlegend (void)
    317  1.1  mrg {
    318  1.1  mrg   puts ("/* Generated automatically by gengenrtl from rtl.def.  */\n");
    319  1.1  mrg }
    320  1.1  mrg 
    321  1.1  mrg /* Generate the text of the header file we make, genrtl.h.  */
    322  1.1  mrg 
    323  1.1  mrg static void
    324  1.1  mrg genheader (void)
    325  1.1  mrg {
    326  1.1  mrg   unsigned int i;
    327  1.1  mrg   const char **fmt;
    328  1.1  mrg 
    329  1.1  mrg   puts ("#ifndef GCC_GENRTL_H");
    330  1.1  mrg   puts ("#define GCC_GENRTL_H\n");
    331  1.1  mrg   puts ("#include \"statistics.h\"\n");
    332  1.1  mrg 
    333  1.1  mrg   for (fmt = formats; *fmt; ++fmt)
    334  1.1  mrg     gendef (*fmt);
    335  1.1  mrg 
    336  1.1  mrg   putchar ('\n');
    337  1.1  mrg 
    338  1.1  mrg   for (i = 0; i < NUM_RTX_CODE; i++)
    339  1.1  mrg     if (! special_format (defs[i].format))
    340  1.1  mrg       genmacro (i);
    341  1.1  mrg 
    342  1.1  mrg   puts ("\n#endif /* GCC_GENRTL_H */");
    343  1.1  mrg }
    344  1.1  mrg 
    345  1.1  mrg /* This is the main program.  */
    346  1.1  mrg 
    347  1.1  mrg int
    348  1.1  mrg main (void)
    349  1.1  mrg {
    350  1.1  mrg   find_formats ();
    351  1.1  mrg   genlegend ();
    352  1.1  mrg 
    353  1.1  mrg   genheader ();
    354  1.1  mrg 
    355  1.1  mrg   if (ferror (stdout) || fflush (stdout) || fclose (stdout))
    356  1.1  mrg     return FATAL_EXIT_CODE;
    357  1.1  mrg 
    358  1.1  mrg   return SUCCESS_EXIT_CODE;
    359           }
    360