Annotation of researchv10dc/cmd/gcc/genemit.c, revision 1.1.1.1

1.1       root        1: /* Generate code from machine description to emit insns as rtl.
                      2:    Copyright (C) 1987 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include <stdio.h>
                     23: #include "config.h"
                     24: #include "rtl.h"
                     25: #include "obstack.h"
                     26: 
                     27: struct obstack obstack;
                     28: struct obstack *rtl_obstack = &obstack;
                     29: 
                     30: #define obstack_chunk_alloc xmalloc
                     31: #define obstack_chunk_free free
                     32: extern int xmalloc ();
                     33: extern void free ();
                     34: 
                     35: void fatal ();
                     36: 
                     37: int max_opno;
                     38: int max_dup_opno;
                     39: int register_constraints;
                     40: int insn_code_number;
                     41: 
                     42: #define max(a, b) ((a) > (b) ? (a) : (b))
                     43: 
                     44: void
                     45: max_operand_1 (x)
                     46:      rtx x;
                     47: {
                     48:   register RTX_CODE code;
                     49:   register int i;
                     50:   register int len;
                     51:   register char *fmt;
                     52: 
                     53:   if (x == 0)
                     54:     return;
                     55: 
                     56:   code = GET_CODE (x);
                     57: 
                     58:   if (code == MATCH_OPERAND && XSTR (x, 2) != 0)
                     59:     register_constraints = 1;
                     60:   if (code == MATCH_OPERAND)
                     61:     max_opno = max (max_opno, XINT (x, 0));
                     62:   if (code == MATCH_DUP)
                     63:     max_dup_opno = max (max_dup_opno, XINT (x, 0));
                     64: 
                     65:   fmt = GET_RTX_FORMAT (code);
                     66:   len = GET_RTX_LENGTH (code);
                     67:   for (i = 0; i < len; i++)
                     68:     {
                     69:       if (fmt[i] == 'e' || fmt[i] == 'u')
                     70:        max_operand_1 (XEXP (x, i));
                     71:       else if (fmt[i] == 'E')
                     72:        {
                     73:          int j;
                     74:          for (j = 0; j < XVECLEN (x, i); j++)
                     75:            max_operand_1 (XVECEXP (x, i, j));
                     76:        }
                     77:     }
                     78: }
                     79: 
                     80: int
                     81: max_operand_vec (insn, arg)
                     82:      rtx insn;
                     83:      int arg;
                     84: {
                     85:   register int len = XVECLEN (insn, arg);
                     86:   register int i;
                     87: 
                     88:   max_opno = -1;
                     89:   max_dup_opno = -1;
                     90: 
                     91:   for (i = 0; i < len; i++)
                     92:     max_operand_1 (XVECEXP (insn, arg, i));
                     93: 
                     94:   return max_opno + 1;
                     95: }
                     96: 
                     97: void
                     98: print_code (code)
                     99:      RTX_CODE code;
                    100: {
                    101:   register char *p1;
                    102:   for (p1 = GET_RTX_NAME (code); *p1; p1++)
                    103:     {
                    104:       if (*p1 >= 'a' && *p1 <= 'z')
                    105:        putchar (*p1 + 'A' - 'a');
                    106:       else
                    107:        putchar (*p1);
                    108:     }
                    109: }
                    110: 
                    111: /* Print a C expression to construct an RTX just like X,
                    112:    substituting any operand references appearing within.  */
                    113: 
                    114: void
                    115: gen_exp (x)
                    116:      rtx x;
                    117: {
                    118:   register RTX_CODE code;
                    119:   register int i;
                    120:   register int len;
                    121:   register char *fmt;
                    122: 
                    123:   if (x == 0)
                    124:     {
                    125:       printf ("0");
                    126:       return;
                    127:     }
                    128: 
                    129:   code = GET_CODE (x);
                    130: 
                    131:   switch (code)
                    132:     {
                    133:     case MATCH_OPERAND:
                    134:     case MATCH_DUP:
                    135:       printf ("operand%d", XINT (x, 0));
                    136:       return;
                    137: 
                    138:     case ADDRESS:
                    139:       fatal ("ADDRESS expression code used in named instruction pattern");
                    140: 
                    141:     case PC:
                    142:       printf ("pc_rtx");
                    143:       return;
                    144: 
                    145:     case CC0:
                    146:       printf ("cc0_rtx");
                    147:       return;
                    148: 
                    149:     case CONST_INT:
                    150:       if (INTVAL (x) == 0)
                    151:        {
                    152:          printf ("const0_rtx");
                    153:          return;
                    154:        }
                    155:       if (INTVAL (x) == 1)
                    156:        {
                    157:          printf ("const1_rtx");
                    158:          return;
                    159:        }
                    160:     }
                    161: 
                    162:   printf ("gen_rtx (");
                    163:   print_code (code);
                    164:   printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
                    165: 
                    166:   fmt = GET_RTX_FORMAT (code);
                    167:   len = GET_RTX_LENGTH (code);
                    168:   for (i = 0; i < len; i++)
                    169:     {
                    170:       if (fmt[i] == '0')
                    171:        break;
                    172:       printf (", ");
                    173:       if (fmt[i] == 'e' || fmt[i] == 'u')
                    174:        gen_exp (XEXP (x, i));
                    175:       else if (fmt[i] == 'i')
                    176:        printf ("%d", XINT (x, i));
                    177:       else if (fmt[i] == 's')
                    178:        printf ("\"%s\"", XSTR (x, i));
                    179:       else if (fmt[i] == 'E')
                    180:        {
                    181:          int j;
                    182:          printf ("gen_rtvec (%d", XVECLEN (x, i));
                    183:          for (j = 0; j < XVECLEN (x, i); j++)
                    184:            {
                    185:              printf (", ");
                    186:              gen_exp (XVECEXP (x, i, j));
                    187:            }
                    188:          printf (")");
                    189:        }
                    190:       else
                    191:        abort ();
                    192:     }
                    193:   printf (")");
                    194: }  
                    195: 
                    196: /* Generate the `gen_...' function for a DEFINE_INSN.  */
                    197: 
                    198: void
                    199: gen_insn (insn)
                    200:      rtx insn;
                    201: {
                    202:   int operands;
                    203:   register int i;
                    204: 
                    205:   /* Don't mention instructions whose names are the null string.
                    206:      They are in the machine description just to be recognized.  */
                    207:   if (strlen (XSTR (insn, 0)) == 0)
                    208:     return;
                    209: 
                    210:   /* Find out how many operands this function has,
                    211:      and also whether any of them have register constraints.  */
                    212:   register_constraints = 0;
                    213:   operands = max_operand_vec (insn, 1);
                    214:   if (max_dup_opno >= operands)
                    215:     fatal ("match_dup operand number has no match_operand");
                    216: 
                    217:   /* Output the function name and argument declarations.  */
                    218:   printf ("rtx\ngen_%s (", XSTR (insn, 0));
                    219:   for (i = 0; i < operands; i++)
                    220:     printf (i ? ", operand%d" : "operand%d", i);
                    221:   printf (")\n");
                    222:   for (i = 0; i < operands; i++)
                    223:     printf ("     rtx operand%d;\n", i);
                    224:   printf ("{\n");
                    225: 
                    226:   /* Output code to construct and return the rtl for the instruction body */
                    227: 
                    228:   if (XVECLEN (insn, 1) == 1)
                    229:     {
                    230:       printf ("  return ");
                    231:       gen_exp (XVECEXP (insn, 1, 0));
                    232:       printf (";\n}\n\n");
                    233:     }
                    234:   else
                    235:     {
                    236:       printf ("  return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1));
                    237:       for (i = 0; i < XVECLEN (insn, 1); i++)
                    238:        {
                    239:          printf (",\n\t\t");
                    240:          gen_exp (XVECEXP (insn, 1, i));
                    241:        }
                    242:       printf ("));\n}\n\n");
                    243:     }
                    244: }
                    245: 
                    246: /* Generate the `gen_...' function for a DEFINE_EXPAND.  */
                    247: 
                    248: void
                    249: gen_expand (expand)
                    250:      rtx expand;
                    251: {
                    252:   int operands;
                    253:   register int i;
                    254: 
                    255:   if (strlen (XSTR (expand, 0)) == 0)
                    256:     fatal ("define_expand lacks a name");
                    257:   if (XVEC (expand, 1) == 0)
                    258:     fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
                    259: 
                    260:   /* Find out how many operands this function has,
                    261:      and also whether any of them have register constraints.  */
                    262:   register_constraints = 0;
                    263: 
                    264:   operands = max_operand_vec (expand, 1);
                    265: 
                    266:   /* Output the function name and argument declarations.  */
                    267:   printf ("rtx\ngen_%s (", XSTR (expand, 0));
                    268:   for (i = 0; i < operands; i++)
                    269:     printf (i ? ", operand%d" : "operand%d", i);
                    270:   printf (")\n");
                    271:   for (i = 0; i < operands; i++)
                    272:     printf ("     rtx operand%d;\n", i);
                    273:   printf ("{\n");
                    274: 
                    275:   /* For each operand referred to only with MATCH_DUPs,
                    276:      make a local variable.  */
                    277:   for (i = operands; i <= max_dup_opno; i++)
                    278:     printf ("  rtx operand%d;\n", i);
                    279:   printf ("  rtx operands[%d];\n\n", max (operands, max_dup_opno + 1));
                    280:   printf ("  extern rtx gen_sequence ();\n");
                    281:   printf ("  extern int emit_to_sequence;\n\n");
                    282:   printf ("  emit_to_sequence++;\n");
                    283: 
                    284:   /* The fourth operand of DEFINE_EXPAND is some code to be executed
                    285:      before the actual construction.
                    286:      This code expects to refer to `operands'
                    287:      just as the output-code in a DEFINE_INSN does,
                    288:      but here `operands' is an automatic array.
                    289:      So copy the operand values there before executing it.  */
                    290:   if (XSTR (expand, 3))
                    291:     {
                    292:       /* Output code to copy the arguments into `operands'.  */
                    293:       for (i = 0; i < operands; i++)
                    294:        printf ("  operands[%d] = operand%d;\n", i, i);
                    295: 
                    296:       /* Output the special code to be executed before the sequence
                    297:         is generated.  */
                    298:       printf ("%s\n", XSTR (expand, 3));
                    299: 
                    300:       /* Output code to copy the arguments back out of `operands'
                    301:         (unless we aren't going to use them at all).  */
                    302:       if (XVEC (expand, 1) != 0)
                    303:        {
                    304:          for (i = 0; i < operands; i++)
                    305:            printf ("  operand%d = operands[%d];\n", i, i);
                    306:          for (; i <= max_dup_opno; i++)
                    307:            printf ("  operand%d = operands[%d];\n", i, i);
                    308:        }
                    309:     }
                    310: 
                    311:   /* Output code to construct the rtl for the instruction bodies.
                    312:      Use emit_insn to add them to the sequence being accumulated.
                    313:      But don't do this if the user's code has set `no_more' nonzero.  */
                    314: 
                    315:   for (i = 0; i < XVECLEN (expand, 1); i++)
                    316:     {
                    317:       rtx next = XVECEXP (expand, 1, i);
                    318:       if ((GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC)
                    319:          || (GET_CODE (next) == PARALLEL
                    320:              && GET_CODE (XVECEXP (next, 0, 0)) == SET
                    321:              && GET_CODE (SET_DEST (XVECEXP (next, 0, 0))) == PC)
                    322:          || GET_CODE (next) == RETURN)
                    323:        printf ("  emit_jump_insn (");
                    324:       else if ((GET_CODE (next) == SET && GET_CODE (SET_SRC (next)) == CALL)
                    325:               || GET_CODE (next) == CALL)
                    326:        printf ("  emit_call_insn (");
                    327:       else if (GET_CODE (next) == CODE_LABEL)
                    328:        printf ("  emit_label (");
                    329:       else if (GET_CODE (next) == MATCH_OPERAND
                    330:               || GET_CODE (next) == MATCH_DUP)
                    331:        printf ("  emit (");
                    332:       else
                    333:        printf ("  emit_insn (");
                    334:       gen_exp (next);
                    335:       printf (");\n");
                    336:       if (GET_CODE (next) == SET && GET_CODE (SET_DEST (next)) == PC
                    337:          && GET_CODE (SET_SRC (next)) == LABEL_REF)
                    338:        printf ("  emit_barrier ();");
                    339:     }
                    340: 
                    341:   printf ("  emit_to_sequence--;\n");
                    342: 
                    343:   /* Call `gen_sequence' to make a SEQUENCE out of all the
                    344:      insns emitted within this gen_... function.  */
                    345: 
                    346:   printf ("  return gen_sequence ();\n}\n\n");
                    347: }
                    348: 
                    349: int
                    350: xmalloc (size)
                    351: {
                    352:   register int val = malloc (size);
                    353: 
                    354:   if (val == 0)
                    355:     fatal ("virtual memory exhausted");
                    356: 
                    357:   return val;
                    358: }
                    359: 
                    360: int
                    361: xrealloc (ptr, size)
                    362:      char *ptr;
                    363:      int size;
                    364: {
                    365:   int result = realloc (ptr, size);
                    366:   if (!result)
                    367:     fatal ("virtual memory exhausted");
                    368:   return result;
                    369: }
                    370: 
                    371: void
                    372: fatal (s, a1, a2)
                    373: {
                    374:   fprintf (stderr, "genemit: ");
                    375:   fprintf (stderr, s, a1, a2);
                    376:   fprintf (stderr, "\n");
                    377:   exit (FATAL_EXIT_CODE);
                    378: }
                    379: 
                    380: int
                    381: main (argc, argv)
                    382:      int argc;
                    383:      char **argv;
                    384: {
                    385:   rtx desc;
                    386:   FILE *infile;
                    387:   extern rtx read_rtx ();
                    388:   register int c;
                    389: 
                    390:   obstack_init (rtl_obstack);
                    391: 
                    392:   if (argc <= 1)
                    393:     fatal ("No input file name.");
                    394: 
                    395:   infile = fopen (argv[1], "r");
                    396:   if (infile == 0)
                    397:     {
                    398:       perror (argv[1]);
                    399:       exit (FATAL_EXIT_CODE);
                    400:     }
                    401: 
                    402:   init_rtl ();
                    403: 
                    404:   /* Assign sequential codes to all entries in the machine description
                    405:      in parallel with the tables in insn-output.c.  */
                    406: 
                    407:   insn_code_number = 0;
                    408: 
                    409:   printf ("/* Generated automatically by the program `genemit'\n\
                    410: from the machine description file `md'.  */\n\n");
                    411: 
                    412:   printf ("#include \"config.h\"\n");
                    413:   printf ("#include \"rtl.h\"\n");
                    414:   printf ("#include \"expr.h\"\n");
                    415:   printf ("#include \"insn-config.h\"\n\n");
                    416:   printf ("extern char *insn_operand_constraint[][MAX_RECOG_OPERANDS];\n\n");
                    417:   printf ("extern rtx recog_operand[];\n");
                    418:   printf ("#define operands recog_operand\n\n");
                    419:   printf ("#define FAIL do { emit_to_sequence--; return 0;} while (0)\n\n");
                    420:   printf ("#define DONE do { emit_to_sequence--; return gen_sequence ();} while (0)\n\n");
                    421: 
                    422:   /* Read the machine description.  */
                    423: 
                    424:   while (1)
                    425:     {
                    426:       c = read_skip_spaces (infile);
                    427:       if (c == EOF)
                    428:        break;
                    429:       ungetc (c, infile);
                    430: 
                    431:       desc = read_rtx (infile);
                    432:       if (GET_CODE (desc) == DEFINE_INSN)
                    433:        {
                    434:          gen_insn (desc);
                    435:          ++insn_code_number;
                    436:        }
                    437:       if (GET_CODE (desc) == DEFINE_EXPAND)
                    438:        {
                    439:          gen_expand (desc);
                    440:          ++insn_code_number;
                    441:        }
                    442:       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
                    443:        {
                    444:          ++insn_code_number;
                    445:        }
                    446:     }
                    447: 
                    448:   fflush (stdout);
                    449:   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
                    450: }

unix.superglobalmegacorp.com

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