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

1.1     ! root        1: /* Generate attribute information (insn-attr.h) from machine description.
        !             2:    Copyright (C) 1991 Free Software Foundation, Inc.
        !             3:    Contributed by Richard Kenner ([email protected])
        !             4: 
        !             5: This file is part of GNU CC.
        !             6: 
        !             7: GNU CC is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU General Public License as published by
        !             9: the Free Software Foundation; either version 2, or (at your option)
        !            10: any later version.
        !            11: 
        !            12: GNU CC is distributed in the hope that it will be useful,
        !            13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with GNU CC; see the file COPYING.  If not, write to
        !            19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            20: 
        !            21: 
        !            22: #include <stdio.h>
        !            23: #include "hconfig.h"
        !            24: #include "rtl.h"
        !            25: #include "obstack.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 PROTO((void *));
        !            34: extern int atoi PROTO((char *));
        !            35: extern rtx read_rtx PROTO((FILE *));
        !            36: 
        !            37: char *xmalloc PROTO((unsigned));
        !            38: static void fatal ();
        !            39: void fancy_abort PROTO((void));
        !            40: 
        !            41: /* A range of values.  */
        !            42: 
        !            43: struct range
        !            44: {
        !            45:   int min;
        !            46:   int max;
        !            47: };
        !            48: 
        !            49: /* Record information about each function unit mentioned in a
        !            50:    DEFINE_FUNCTION_UNIT.  */
        !            51: 
        !            52: struct function_unit
        !            53: {
        !            54:   char *name;                  /* Function unit name.  */
        !            55:   struct function_unit *next;  /* Next function unit.  */
        !            56:   int multiplicity;            /* Number of units of this type.  */
        !            57:   int simultaneity;            /* Maximum number of simultaneous insns
        !            58:                                   on this function unit or 0 if unlimited.  */
        !            59:   struct range ready_cost;     /* Range of ready cost values.  */
        !            60:   struct range issue_delay;    /* Range of issue delay values.  */
        !            61: };
        !            62: 
        !            63: static void
        !            64: extend_range (range, min, max)
        !            65:      struct range *range;
        !            66:      int min;
        !            67:      int max;
        !            68: {
        !            69:   if (range->min > min) range->min = min;
        !            70:   if (range->max < max) range->max = max;
        !            71: }
        !            72: 
        !            73: static void
        !            74: init_range (range)
        !            75:      struct range *range;
        !            76: {
        !            77:   range->min = 100000;
        !            78:   range->max = -1;
        !            79: }
        !            80: 
        !            81: static void
        !            82: write_upcase (str)
        !            83:     char *str;
        !            84: {
        !            85:   for (; *str; str++)
        !            86:     if (*str >= 'a' && *str <= 'z')
        !            87:       printf ("%c", *str - 'a' + 'A');
        !            88:     else
        !            89:       printf ("%c", *str);
        !            90: }
        !            91: 
        !            92: static void
        !            93: gen_attr (attr)
        !            94:      rtx attr;
        !            95: {
        !            96:   char *p;
        !            97: 
        !            98:   printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0));
        !            99: 
        !           100:   /* If numeric attribute, don't need to write an enum.  */
        !           101:   if (*XSTR (attr, 1) == '\0')
        !           102:     printf ("extern int get_attr_%s ();\n", XSTR (attr, 0));
        !           103:   else
        !           104:     {
        !           105:       printf ("enum attr_%s {", XSTR (attr, 0));
        !           106:       write_upcase (XSTR (attr, 0));
        !           107:       printf ("_");
        !           108: 
        !           109:       for (p = XSTR (attr, 1); *p != '\0'; p++)
        !           110:        {
        !           111:          if (*p == ',')
        !           112:            {
        !           113:              printf (", ");
        !           114:              write_upcase (XSTR (attr, 0));
        !           115:              printf ("_");
        !           116:            }
        !           117:          else if (*p >= 'a' && *p <= 'z')
        !           118:            printf ("%c", *p - 'a' + 'A');
        !           119:          else
        !           120:            printf ("%c", *p);
        !           121:        }
        !           122: 
        !           123:       printf ("};\n");
        !           124:       printf ("extern enum attr_%s get_attr_%s ();\n\n",
        !           125:              XSTR (attr, 0), XSTR (attr, 0));
        !           126:     }
        !           127: 
        !           128:   /* If `length' attribute, write additional function definitions and define
        !           129:      variables used by `insn_current_length'.  */
        !           130:   if (! strcmp (XSTR (attr, 0), "length"))
        !           131:     {
        !           132:       printf ("extern void init_lengths ();\n");
        !           133:       printf ("extern void shorten_branches PROTO((rtx));\n");
        !           134:       printf ("extern int insn_default_length PROTO((rtx));\n");
        !           135:       printf ("extern int insn_variable_length_p PROTO((rtx));\n");
        !           136:       printf ("extern int insn_current_length PROTO((rtx));\n\n");
        !           137:       printf ("extern int *insn_addresses;\n");
        !           138:       printf ("extern int insn_current_address;\n\n");
        !           139:     }
        !           140: }
        !           141: 
        !           142: static void
        !           143: write_units (num_units, multiplicity, simultaneity,
        !           144:             ready_cost, issue_delay, blockage)
        !           145:      int num_units;
        !           146:      struct range *multiplicity;
        !           147:      struct range *simultaneity;
        !           148:      struct range *ready_cost;
        !           149:      struct range *issue_delay;
        !           150:      struct range *blockage;
        !           151: {
        !           152:   int i, q_size;
        !           153: 
        !           154:   printf ("#define INSN_SCHEDULING\n\n");
        !           155:   printf ("extern int result_ready_cost PROTO((rtx));\n");
        !           156:   printf ("extern int function_units_used PROTO((rtx));\n\n");
        !           157:   printf ("extern struct function_unit_desc\n");
        !           158:   printf ("{\n");
        !           159:   printf ("  char *name;\n");
        !           160:   printf ("  int bitmask;\n");
        !           161:   printf ("  int multiplicity;\n");
        !           162:   printf ("  int simultaneity;\n");
        !           163:   printf ("  int default_cost;\n");
        !           164:   printf ("  int max_issue_delay;\n");
        !           165:   printf ("  int (*ready_cost_function) ();\n");
        !           166:   printf ("  int (*conflict_cost_function) ();\n");
        !           167:   printf ("  int max_blockage;\n");
        !           168:   printf ("  unsigned int (*blockage_range_function) ();\n");
        !           169:   printf ("  int (*blockage_function) ();\n");
        !           170:   printf ("} function_units[];\n\n");
        !           171:   printf ("#define FUNCTION_UNITS_SIZE %d\n", num_units);
        !           172:   printf ("#define MIN_MULTIPLICITY %d\n", multiplicity->min);
        !           173:   printf ("#define MAX_MULTIPLICITY %d\n", multiplicity->max);
        !           174:   printf ("#define MIN_SIMULTANEITY %d\n", simultaneity->min);
        !           175:   printf ("#define MAX_SIMULTANEITY %d\n", simultaneity->max);
        !           176:   printf ("#define MIN_READY_COST %d\n", ready_cost->min);
        !           177:   printf ("#define MAX_READY_COST %d\n", ready_cost->max);
        !           178:   printf ("#define MIN_ISSUE_DELAY %d\n", issue_delay->min);
        !           179:   printf ("#define MAX_ISSUE_DELAY %d\n", issue_delay->max);
        !           180:   printf ("#define MIN_BLOCKAGE %d\n", blockage->min);
        !           181:   printf ("#define MAX_BLOCKAGE %d\n", blockage->max);
        !           182:   for (i = 0; (1 << i) < blockage->max; i++)
        !           183:     ;
        !           184:   printf ("#define BLOCKAGE_BITS %d\n", i + 1);
        !           185: 
        !           186:   /* INSN_QUEUE_SIZE is a power of two larger than MAX_BLOCKAGE and
        !           187:      MAX_READY_COST.  This is the longest time an isnsn may be queued.  */
        !           188:   i = MAX (blockage->max, ready_cost->max);
        !           189:   for (q_size = 1; q_size <= i; q_size <<= 1)
        !           190:     ;
        !           191:   printf ("#define INSN_QUEUE_SIZE %d\n", q_size);
        !           192: }
        !           193: 
        !           194: char *
        !           195: xmalloc (size)
        !           196:      unsigned size;
        !           197: {
        !           198:   register char *val = (char *) malloc (size);
        !           199: 
        !           200:   if (val == 0)
        !           201:     fatal ("virtual memory exhausted");
        !           202:   return val;
        !           203: }
        !           204: 
        !           205: char *
        !           206: xrealloc (ptr, size)
        !           207:      char *ptr;
        !           208:      unsigned size;
        !           209: {
        !           210:   char * result = (char *) realloc (ptr, size);
        !           211:   if (!result)
        !           212:     fatal ("virtual memory exhausted");
        !           213:   return result;
        !           214: }
        !           215: 
        !           216: static void
        !           217: fatal (s, a1, a2)
        !           218:      char *s;
        !           219: {
        !           220:   fprintf (stderr, "genattr: ");
        !           221:   fprintf (stderr, s, a1, a2);
        !           222:   fprintf (stderr, "\n");
        !           223:   exit (FATAL_EXIT_CODE);
        !           224: }
        !           225: 
        !           226: /* More 'friendly' abort that prints the line and file.
        !           227:    config.h can #define abort fancy_abort if you like that sort of thing.  */
        !           228: 
        !           229: void
        !           230: fancy_abort ()
        !           231: {
        !           232:   fatal ("Internal gcc abort.");
        !           233: }
        !           234: 
        !           235: int
        !           236: main (argc, argv)
        !           237:      int argc;
        !           238:      char **argv;
        !           239: {
        !           240:   rtx desc;
        !           241:   FILE *infile;
        !           242:   register int c;
        !           243:   int have_delay = 0;
        !           244:   int have_annul_true = 0;
        !           245:   int have_annul_false = 0;
        !           246:   int num_units = 0;
        !           247:   struct range all_simultaneity, all_multiplicity;
        !           248:   struct range all_ready_cost, all_issue_delay, all_blockage;
        !           249:   struct function_unit *units = 0, *unit;
        !           250:   int i;
        !           251: 
        !           252:   init_range (&all_multiplicity);
        !           253:   init_range (&all_simultaneity);
        !           254:   init_range (&all_ready_cost);
        !           255:   init_range (&all_issue_delay);
        !           256:   init_range (&all_blockage);
        !           257: 
        !           258:   obstack_init (rtl_obstack);
        !           259: 
        !           260:   if (argc <= 1)
        !           261:     fatal ("No input file name.");
        !           262: 
        !           263:   infile = fopen (argv[1], "r");
        !           264:   if (infile == 0)
        !           265:     {
        !           266:       perror (argv[1]);
        !           267:       exit (FATAL_EXIT_CODE);
        !           268:     }
        !           269: 
        !           270:   init_rtl ();
        !           271: 
        !           272:   printf ("/* Generated automatically by the program `genattr'\n\
        !           273: from the machine description file `md'.  */\n\n");
        !           274: 
        !           275:   /* For compatibility, define the attribute `alternative', which is just
        !           276:      a reference to the variable `which_alternative'.  */
        !           277: 
        !           278:   printf("#ifndef PROTO\n");
        !           279:   printf("#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)\n");
        !           280:   printf("#define PROTO(ARGS) ARGS\n");
        !           281:   printf("#else\n");
        !           282:   printf("#define PROTO(ARGS) ()\n");
        !           283:   printf("#endif\n");
        !           284:   printf("#endif\n");
        !           285: 
        !           286:   printf ("#define HAVE_ATTR_alternative\n");
        !           287:   printf ("#define get_attr_alternative(insn) which_alternative\n");
        !           288:      
        !           289:   /* Read the machine description.  */
        !           290: 
        !           291:   while (1)
        !           292:     {
        !           293:       c = read_skip_spaces (infile);
        !           294:       if (c == EOF)
        !           295:        break;
        !           296:       ungetc (c, infile);
        !           297: 
        !           298:       desc = read_rtx (infile);
        !           299:       if (GET_CODE (desc) == DEFINE_ATTR)
        !           300:        gen_attr (desc);
        !           301: 
        !           302:       else if (GET_CODE (desc) == DEFINE_DELAY)
        !           303:         {
        !           304:          if (! have_delay)
        !           305:            {
        !           306:              printf ("#define DELAY_SLOTS\n");
        !           307:              printf ("extern int num_delay_slots PROTO((rtx));\n");
        !           308:              printf ("extern int eligible_for_delay PROTO((rtx, int, rtx, int));\n\n");
        !           309:              printf ("extern int const_num_delay_slots PROTO((rtx));\n\n");
        !           310:              have_delay = 1;
        !           311:            }
        !           312: 
        !           313:          for (i = 0; i < XVECLEN (desc, 1); i += 3)
        !           314:            {
        !           315:              if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
        !           316:                {
        !           317:                  printf ("#define ANNUL_IFTRUE_SLOTS\n");
        !           318:                  printf ("extern int eligible_for_annul_true ();\n");
        !           319:                  have_annul_true = 1;
        !           320:                }
        !           321: 
        !           322:              if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
        !           323:                {
        !           324:                  printf ("#define ANNUL_IFFALSE_SLOTS\n");
        !           325:                  printf ("extern int eligible_for_annul_false ();\n");
        !           326:                  have_annul_false = 1;
        !           327:                }
        !           328:            }
        !           329:         }
        !           330: 
        !           331:       else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
        !           332:        {
        !           333:          char *name = XSTR (desc, 0);
        !           334:          int multiplicity = XINT (desc, 1);
        !           335:          int simultaneity = XINT (desc, 2);
        !           336:          int ready_cost = MAX (XINT (desc, 4), 1);
        !           337:          int issue_delay = MAX (XINT (desc, 5), 1);
        !           338:          int issueexp_p = (XVEC (desc, 6) != 0);
        !           339: 
        !           340:          for (unit = units; unit; unit = unit->next)
        !           341:            if (strcmp (unit->name, name) == 0)
        !           342:              break;
        !           343: 
        !           344:          if (unit == 0)
        !           345:            {
        !           346:              int len = strlen (name) + 1;
        !           347:              unit = (struct function_unit *)
        !           348:                alloca (sizeof (struct function_unit));
        !           349:              unit->name = (char *) alloca (len);
        !           350:              bcopy (name, unit->name, len);
        !           351:              unit->multiplicity = multiplicity;
        !           352:              unit->simultaneity = simultaneity;
        !           353:              unit->ready_cost.min = unit->ready_cost.max = ready_cost;
        !           354:              unit->issue_delay.min = unit->issue_delay.max = issue_delay;
        !           355:              unit->next = units;
        !           356:              units = unit;
        !           357:              num_units++;
        !           358: 
        !           359:              extend_range (&all_multiplicity, multiplicity, multiplicity);
        !           360:              extend_range (&all_simultaneity, simultaneity, simultaneity);
        !           361:            }
        !           362:          else if (unit->multiplicity != multiplicity
        !           363:                   || unit->simultaneity != simultaneity)
        !           364:            fatal ("Differing specifications given for `%s' function unit.",
        !           365:                   unit->name);
        !           366: 
        !           367:          extend_range (&unit->ready_cost, ready_cost, ready_cost);
        !           368:          extend_range (&unit->issue_delay,
        !           369:                        issueexp_p ? 1 : issue_delay, issue_delay);
        !           370:          extend_range (&all_ready_cost,
        !           371:                        unit->ready_cost.min, unit->ready_cost.max);
        !           372:          extend_range (&all_issue_delay,
        !           373:                        unit->issue_delay.min, unit->issue_delay.max);
        !           374:        }
        !           375:     }
        !           376: 
        !           377:   if (num_units > 0)
        !           378:     {
        !           379:       /* Compute the range of blockage cost values.  See genattrtab.c
        !           380:         for the derivation.  BLOCKAGE (E,C) when SIMULTANEITY is zero is
        !           381: 
        !           382:             MAX (ISSUE-DELAY (E,C),
        !           383:                  READY-COST (E) - (READY-COST (C) - 1))
        !           384: 
        !           385:         and otherwise
        !           386: 
        !           387:             MAX (ISSUE-DELAY (E,C),
        !           388:                  READY-COST (E) - (READY-COST (C) - 1),
        !           389:                  READY-COST (E) - FILL-TIME)  */
        !           390: 
        !           391:       for (unit = units; unit; unit = unit->next)
        !           392:        {
        !           393:          struct range blockage;
        !           394:          int max_issue_time = MAX (unit->issue_delay.max, 1);
        !           395: 
        !           396:          blockage = unit->issue_delay;
        !           397:          blockage.max = MAX (unit->ready_cost.max
        !           398:                              - (unit->ready_cost.min - 1),
        !           399:                              blockage.max);
        !           400:          blockage.min = MAX (1, blockage.min);
        !           401: 
        !           402:          if (unit->simultaneity != 0)
        !           403:            {
        !           404:              int fill_time = ((unit->simultaneity - 1)
        !           405:                               * unit->issue_delay.min);
        !           406:              blockage.min = MAX (unit->ready_cost.min - fill_time,
        !           407:                                  blockage.min);
        !           408:              blockage.max = MAX (unit->ready_cost.max - fill_time,
        !           409:                                  blockage.max);
        !           410:            }
        !           411:          extend_range (&all_blockage, blockage.min, blockage.max);
        !           412:        }
        !           413: 
        !           414:       write_units (num_units, &all_multiplicity, &all_simultaneity,
        !           415:                   &all_ready_cost, &all_issue_delay, &all_blockage);
        !           416:     }
        !           417: 
        !           418:   /* Output flag masks for use by reorg.  
        !           419: 
        !           420:      Flags are used to hold branch direction and prediction information
        !           421:      for use by eligible_for_...  */
        !           422:   printf("\n#define ATTR_FLAG_forward 0x1\n");
        !           423:   printf("#define ATTR_FLAG_backward 0x2\n");
        !           424:   printf("#define ATTR_FLAG_likely 0x4\n");
        !           425:   printf("#define ATTR_FLAG_very_likely 0x8\n");
        !           426:   printf("#define ATTR_FLAG_unlikely 0x10\n");
        !           427:   printf("#define ATTR_FLAG_very_unlikely 0x20\n");
        !           428: 
        !           429:   fflush (stdout);
        !           430:   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
        !           431:   /* NOTREACHED */
        !           432:   return 0;
        !           433: }

unix.superglobalmegacorp.com

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