Annotation of GNUtools/cc/genopinit.c, revision 1.1

1.1     ! root        1: /* Generate code to initialize optabs from machine description.
        !             2:    Copyright (C) 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include "hconfig.h"
        !            23: #include "rtl.h"
        !            24: #include "obstack.h"
        !            25: #include <ctype.h>
        !            26: 
        !            27: static struct obstack obstack;
        !            28: struct obstack *rtl_obstack = &obstack;
        !            29: 
        !            30: #define obstack_chunk_alloc xmalloc
        !            31: #define obstack_chunk_free free
        !            32: 
        !            33: extern void free ();
        !            34: extern rtx read_rtx ();
        !            35: 
        !            36: char *xmalloc ();
        !            37: static void fatal ();
        !            38: void fancy_abort ();
        !            39: 
        !            40: /* Many parts of GCC use arrays that are indexed by machine mode and
        !            41:    contain the insn codes for pattern in the MD file that perform a given
        !            42:    operation on operands of that mode.
        !            43: 
        !            44:    These patterns are present in the MD file with names that contain
        !            45:    the mode(s) used and the name of the operation.  This program
        !            46:    writes a function `init_all_optabs' that initializes the optabs with
        !            47:    all the insn codes of the relevant patterns present in the MD file.
        !            48: 
        !            49:    This array contains a list of optabs that need to be initialized.  Within
        !            50:    each string, the name of the pattern to be matched against is delimited
        !            51:    with %( and %).  In the string, %a and %b are used to match a short mode
        !            52:    name (the part of the mode name not including `mode' and converted to
        !            53:    lower-case).  When writing out the initializer, the entire string is
        !            54:    used.  %A and %B are replaced with the full name of the mode; %a and %b
        !            55:    are replaced with the short form of the name, as above.
        !            56: 
        !            57:    If %N is present in the pattern, it means the two modes must be consecutive
        !            58:    widths in the same mode class (e.g, QImode and HImode).  %I means that
        !            59:    only integer modes should be considered for the next mode, and %F means
        !            60:    that only float modes should be considered.
        !            61: 
        !            62:    For some optabs, we store the operation by RTL codes.  These are only
        !            63:    used for comparisons.  In that case, %c and %C are the lower-case and
        !            64:    upper-case forms of the comparison, respectively.  */
        !            65: 
        !            66: /* The reason we use \% is to avoid sequences of the form %-capletter-%
        !            67:    which SCCS treats as magic.  This gets warnings which you should ignore.  */
        !            68: 
        !            69: char *optabs[] =
        !            70: { "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
        !            71:   "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
        !            72:   "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
        !            73:   "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)",
        !            74:   "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)",
        !            75:   "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)",
        !            76:   "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)",
        !            77:   "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)",
        !            78:   "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)",
        !            79:   "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)",
        !            80:   "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)",
        !            81:   "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N",
        !            82:   "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N",
        !            83:   "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)",
        !            84:   "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)",
        !            85:   "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)",
        !            86:   "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)",
        !            87:   "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)",
        !            88:   "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)",
        !            89:   "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)",
        !            90:   "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)",
        !            91:   "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)",
        !            92:   "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)",
        !            93:   "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)",
        !            94:   "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)",
        !            95:   "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)",
        !            96:   "lshl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshl%a3%)",
        !            97:   "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)",
        !            98:   "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)",
        !            99:   "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)",
        !           100:   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)",
        !           101:   "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)",
        !           102:   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)",
        !           103:   "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)",
        !           104:   "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)",
        !           105:   "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)",
        !           106:   "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)",
        !           107:   "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)",
        !           108:   "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)",
        !           109:   "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)",
        !           110:   "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)",
        !           111:   "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)",
        !           112:   "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)",
        !           113:   "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)",
        !           114:   "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)",
        !           115:   "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)",
        !           116:   "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)",
        !           117:   "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)",
        !           118:   "bcc_gen_fctn[(int) %C] = gen_%(b%c%)",
        !           119:   "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)",
        !           120:   "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)",
        !           121:   "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)",
        !           122:   "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)" };
        !           123: 
        !           124: /* Allow linking with print-rtl.c.  */
        !           125: char **insn_name_ptr;
        !           126: 
        !           127: static void
        !           128: gen_insn (insn)
        !           129:      rtx insn;
        !           130: {
        !           131:   char *name = XSTR (insn, 0);
        !           132:   int m1, m2, op;
        !           133:   int pindex;
        !           134:   int i;
        !           135:   char *np, *pp, *p, *q;
        !           136:   struct obstack *obstack_ptr;
        !           137: 
        !           138:   /* Don't mention instructions whose names are the null string.
        !           139:      They are in the machine description just to be recognized.  */
        !           140:   if (*name == 0)
        !           141:     return;
        !           142: 
        !           143:   /* See if NAME matches one of the patterns we have for the optabs we know
        !           144:      about.  */
        !           145: 
        !           146:   for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++)
        !           147:     {
        !           148:       int force_float = 0, force_int = 0;
        !           149:       int force_consec = 0;
        !           150:       int matches = 1;
        !           151: 
        !           152:       for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++)
        !           153:        ;
        !           154: 
        !           155:       for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')');
        !           156:           pp++)
        !           157:        {
        !           158:          if (*pp != '%')
        !           159:            {
        !           160:              if (*pp != *np++)
        !           161:                break;
        !           162:            }
        !           163:          else
        !           164:            switch (*++pp)
        !           165:              {
        !           166:              case 'N':
        !           167:                force_consec = 1;
        !           168:                break;
        !           169:              case 'I':
        !           170:                force_int = 1;
        !           171:                break;
        !           172:              case 'F':
        !           173:                force_float = 1;
        !           174:                break;
        !           175:              case 'c':
        !           176:                for (op = 0; op < NUM_RTX_CODE; op++)
        !           177:                  {
        !           178:                    for (p = rtx_name[op], q = np; *p; p++, q++)
        !           179:                      if (*p != *q)
        !           180:                        break;
        !           181: 
        !           182:                    /* We have to be concerned about matching "gt" and
        !           183:                       missing "gtu", e.g., so verify we have reached the
        !           184:                       end of thing we are to match.  We do not have this
        !           185:                       problem with modes since no mode is a prefix of
        !           186:                       another.  */
        !           187:                    if (*p == 0 && *q == 0 && rtx_class[op] == '<')
        !           188:                      break;
        !           189:                  }
        !           190: 
        !           191:                if (op == NUM_RTX_CODE)
        !           192:                  matches = 0;
        !           193:                else
        !           194:                  np += strlen (rtx_name[op]);
        !           195:                break;
        !           196:              case 'a':
        !           197:              case 'b':
        !           198:                for (i = 0; i < (int) MAX_MACHINE_MODE; i++)
        !           199:                  {
        !           200:                    for (p = mode_name[i], q = np; *p; p++, q++)
        !           201:                      if (tolower (*p) != *q)
        !           202:                        break;
        !           203: 
        !           204:                    if (*p == 0
        !           205:                        && (! force_int || mode_class[i] == MODE_INT)
        !           206:                        && (! force_float || mode_class[i] == MODE_FLOAT))
        !           207:                      break;
        !           208:                  }
        !           209: 
        !           210:                if (i == (int) MAX_MACHINE_MODE)
        !           211:                  matches = 0;
        !           212:                else if (*pp == 'a')
        !           213:                  m1 = i, np += strlen (mode_name[i]);
        !           214:                else
        !           215:                  m2 = i, np += strlen (mode_name[i]);
        !           216: 
        !           217:                force_int = force_float = 0;
        !           218:                break;
        !           219: 
        !           220:              default:
        !           221:                abort ();
        !           222:              }
        !           223:        }
        !           224: 
        !           225:       if (matches && pp[0] == '%' && pp[1] == ')'
        !           226:          && *np == 0
        !           227:          && (! force_consec || (int) mode_wider_mode[m1] == m2))
        !           228:        break;
        !           229:     }
        !           230: 
        !           231:   if (pindex == sizeof optabs / sizeof optabs[0])
        !           232:     return;
        !           233: 
        !           234:   /* We found a match.  If this pattern is only conditionally present,
        !           235:      write out the "if" and two extra blanks.  */
        !           236: 
        !           237:   if (*XSTR (insn, 2) != 0)
        !           238:     printf ("  if (HAVE_%s)\n  ", name);
        !           239: 
        !           240:   printf ("  ");
        !           241: 
        !           242:   /* Now write out the initialization, making all required substitutions.  */
        !           243:   for (pp = optabs[pindex]; *pp; pp++)
        !           244:     {
        !           245:       if (*pp != '%')
        !           246:        printf ("%c", *pp);
        !           247:       else
        !           248:        switch (*++pp)
        !           249:          {
        !           250:          case '(':  case ')':
        !           251:          case 'I':  case 'F':  case 'N':
        !           252:            break;
        !           253:          case 'a':
        !           254:            for (np = mode_name[m1]; *np; np++)
        !           255:              printf ("%c", tolower (*np));
        !           256:            break;
        !           257:          case 'b':
        !           258:            for (np = mode_name[m2]; *np; np++)
        !           259:              printf ("%c", tolower (*np));
        !           260:            break;
        !           261:          case 'A':
        !           262:            printf ("%smode", mode_name[m1]);
        !           263:            break;
        !           264:          case 'B':
        !           265:            printf ("%smode", mode_name[m2]);
        !           266:            break;
        !           267:          case 'c':
        !           268:            printf ("%s", rtx_name[op]);
        !           269:            break;
        !           270:          case 'C':
        !           271:            for (np = rtx_name[op]; *np; np++)
        !           272:              printf ("%c", toupper (*np));
        !           273:            break;
        !           274:          }
        !           275:     }
        !           276: 
        !           277:   printf (";\n");
        !           278: }
        !           279: 
        !           280: char *
        !           281: xmalloc (size)
        !           282:      unsigned size;
        !           283: {
        !           284:   register char *val = (char *) malloc (size);
        !           285: 
        !           286:   if (val == 0)
        !           287:     fatal ("virtual memory exhausted");
        !           288: 
        !           289:   return val;
        !           290: }
        !           291: 
        !           292: char *
        !           293: xrealloc (ptr, size)
        !           294:      char *ptr;
        !           295:      unsigned size;
        !           296: {
        !           297:   char *result = (char *) realloc (ptr, size);
        !           298:   if (!result)
        !           299:     fatal ("virtual memory exhausted");
        !           300:   return result;
        !           301: }
        !           302: 
        !           303: static void
        !           304: fatal (s, a1, a2)
        !           305:      char *s;
        !           306: {
        !           307:   fprintf (stderr, "genopinit: ");
        !           308:   fprintf (stderr, s, a1, a2);
        !           309:   fprintf (stderr, "\n");
        !           310:   exit (FATAL_EXIT_CODE);
        !           311: }
        !           312: 
        !           313: /* More 'friendly' abort that prints the line and file.
        !           314:    config.h can #define abort fancy_abort if you like that sort of thing.  */
        !           315: 
        !           316: void
        !           317: fancy_abort ()
        !           318: {
        !           319:   fatal ("Internal gcc abort.");
        !           320: }
        !           321: 
        !           322: int
        !           323: main (argc, argv)
        !           324:      int argc;
        !           325:      char **argv;
        !           326: {
        !           327:   rtx desc;
        !           328:   rtx dummy;
        !           329:   rtx *insn_ptr;
        !           330:   FILE *infile;
        !           331:   register int c;
        !           332: 
        !           333:   obstack_init (rtl_obstack);
        !           334: 
        !           335:   if (argc <= 1)
        !           336:     fatal ("No input file name.");
        !           337: 
        !           338:   infile = fopen (argv[1], "r");
        !           339:   if (infile == 0)
        !           340:     {
        !           341:       perror (argv[1]);
        !           342:       exit (FATAL_EXIT_CODE);
        !           343:     }
        !           344: 
        !           345:   init_rtl ();
        !           346: 
        !           347:   printf ("/* Generated automatically by the program `genopinit'\n\
        !           348: from the machine description file `md'.  */\n\n");
        !           349: 
        !           350:   printf ("#include \"config.h\"\n");
        !           351:   printf ("#include \"rtl.h\"\n");
        !           352:   printf ("#include \"flags.h\"\n");
        !           353:   printf ("#include \"insn-flags.h\"\n");
        !           354:   printf ("#include \"insn-codes.h\"\n");
        !           355:   printf ("#include \"insn-config.h\"\n");
        !           356:   printf ("#include \"recog.h\"\n");
        !           357:   printf ("#include \"expr.h\"\n");
        !           358:   printf ("#include \"reload.h\"\n\n");
        !           359: 
        !           360:   printf ("void\ninit_all_optabs ()\n{\n");
        !           361: 
        !           362:   /* Read the machine description.  */
        !           363: 
        !           364:   while (1)
        !           365:     {
        !           366:       c = read_skip_spaces (infile);
        !           367:       if (c == EOF)
        !           368:        break;
        !           369:       ungetc (c, infile);
        !           370: 
        !           371:       desc = read_rtx (infile);
        !           372:       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
        !           373:        gen_insn (desc);
        !           374:     }
        !           375: 
        !           376:   printf ("}\n");
        !           377: 
        !           378:   fflush (stdout);
        !           379:   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
        !           380:   /* NOTREACHED */
        !           381:   return 0;
        !           382: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.