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