|
|
1.1 ! root 1: /* Generate from machine description: ! 2: ! 3: - some flags HAVE_... saying which simple standard instructions are ! 4: available for this machine. ! 5: Copyright (C) 1987, 1991 Free Software Foundation, Inc. ! 6: ! 7: This file is part of GNU CC. ! 8: ! 9: GNU CC is free software; you can redistribute it and/or modify ! 10: it under the terms of the GNU General Public License as published by ! 11: the Free Software Foundation; either version 2, or (at your option) ! 12: any later version. ! 13: ! 14: GNU CC is distributed in the hope that it will be useful, ! 15: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: GNU General Public License for more details. ! 18: ! 19: You should have received a copy of the GNU General Public License ! 20: along with GNU CC; see the file COPYING. If not, write to ! 21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 22: ! 23: ! 24: #include <stdio.h> ! 25: #include "hconfig.h" ! 26: #include "rtl.h" ! 27: #include "obstack.h" ! 28: ! 29: static struct obstack obstack; ! 30: struct obstack *rtl_obstack = &obstack; ! 31: ! 32: #define obstack_chunk_alloc xmalloc ! 33: #define obstack_chunk_free free ! 34: ! 35: extern void free (); ! 36: extern rtx read_rtx (); ! 37: ! 38: char *xmalloc (); ! 39: static void fatal (); ! 40: void fancy_abort (); ! 41: ! 42: /* Names for patterns. Need to allow linking with print-rtl. */ ! 43: char **insn_name_ptr; ! 44: ! 45: /* Obstacks to remember normal, and call insns. */ ! 46: static struct obstack call_obstack, normal_obstack; ! 47: ! 48: /* Max size of names encountered. */ ! 49: static int max_id_len; ! 50: ! 51: /* Count the number of match_operand's found. */ ! 52: static int ! 53: num_operands (x) ! 54: rtx x; ! 55: { ! 56: int count = 0; ! 57: int i, j; ! 58: enum rtx_code code = GET_CODE (x); ! 59: char *format_ptr = GET_RTX_FORMAT (code); ! 60: ! 61: if (code == MATCH_OPERAND) ! 62: return 1; ! 63: ! 64: if (code == MATCH_OPERATOR || code == MATCH_PARALLEL) ! 65: count++; ! 66: ! 67: for (i = 0; i < GET_RTX_LENGTH (code); i++) ! 68: { ! 69: switch (*format_ptr++) ! 70: { ! 71: case 'u': ! 72: case 'e': ! 73: count += num_operands (XEXP (x, i)); ! 74: break; ! 75: ! 76: case 'E': ! 77: if (XVEC (x, i) != NULL) ! 78: for (j = 0; j < XVECLEN (x, i); j++) ! 79: count += num_operands (XVECEXP (x, i, j)); ! 80: ! 81: break; ! 82: } ! 83: } ! 84: ! 85: return count; ! 86: } ! 87: ! 88: /* Print out prototype information for a function. */ ! 89: static void ! 90: gen_proto (insn) ! 91: rtx insn; ! 92: { ! 93: int num = num_operands (insn); ! 94: printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0)); ! 95: ! 96: if (num == 0) ! 97: printf ("void"); ! 98: else ! 99: { ! 100: while (num-- > 1) ! 101: printf ("rtx, "); ! 102: ! 103: printf ("rtx"); ! 104: } ! 105: ! 106: printf ("));\n"); ! 107: } ! 108: ! 109: /* Print out a function declaration without a prototype. */ ! 110: static void ! 111: gen_nonproto (insn) ! 112: rtx insn; ! 113: { ! 114: printf ("extern rtx gen_%s ();\n", XSTR (insn, 0)); ! 115: } ! 116: ! 117: static void ! 118: gen_insn (insn) ! 119: rtx insn; ! 120: { ! 121: char *name = XSTR (insn, 0); ! 122: char *p; ! 123: struct obstack *obstack_ptr; ! 124: int len; ! 125: ! 126: /* Don't mention instructions whose names are the null string. ! 127: They are in the machine description just to be recognized. */ ! 128: len = strlen (name); ! 129: if (len == 0) ! 130: return; ! 131: ! 132: if (len > max_id_len) ! 133: max_id_len = len; ! 134: ! 135: printf ("#define HAVE_%s ", name); ! 136: if (strlen (XSTR (insn, 2)) == 0) ! 137: printf ("1\n"); ! 138: else ! 139: { ! 140: /* Write the macro definition, putting \'s at the end of each line, ! 141: if more than one. */ ! 142: printf ("("); ! 143: for (p = XSTR (insn, 2); *p; p++) ! 144: { ! 145: if (*p == '\n') ! 146: printf (" \\\n"); ! 147: else ! 148: printf ("%c", *p); ! 149: } ! 150: printf (")\n"); ! 151: } ! 152: ! 153: /* Save the current insn, so that we can later put out appropriate ! 154: prototypes. At present, most md files have the wrong number of ! 155: arguments for the call insns (call, call_value, call_pop, ! 156: call_value_pop) ignoring the extra arguments that are passed for ! 157: some machines, so by default, turn off the prototype. */ ! 158: ! 159: obstack_ptr = (name[0] == 'c' ! 160: && (!strcmp (name, "call") ! 161: || !strcmp (name, "call_value") ! 162: || !strcmp (name, "call_pop") ! 163: || !strcmp (name, "call_value_pop"))) ! 164: ? &call_obstack : &normal_obstack; ! 165: ! 166: obstack_grow (obstack_ptr, &insn, sizeof (rtx)); ! 167: } ! 168: ! 169: char * ! 170: xmalloc (size) ! 171: unsigned size; ! 172: { ! 173: register char *val = (char *) malloc (size); ! 174: ! 175: if (val == 0) ! 176: fatal ("virtual memory exhausted"); ! 177: ! 178: return val; ! 179: } ! 180: ! 181: char * ! 182: xrealloc (ptr, size) ! 183: char *ptr; ! 184: unsigned size; ! 185: { ! 186: char *result = (char *) realloc (ptr, size); ! 187: if (!result) ! 188: fatal ("virtual memory exhausted"); ! 189: return result; ! 190: } ! 191: ! 192: static void ! 193: fatal (s, a1, a2) ! 194: char *s; ! 195: { ! 196: fprintf (stderr, "genflags: "); ! 197: fprintf (stderr, s, a1, a2); ! 198: fprintf (stderr, "\n"); ! 199: exit (FATAL_EXIT_CODE); ! 200: } ! 201: ! 202: /* More 'friendly' abort that prints the line and file. ! 203: config.h can #define abort fancy_abort if you like that sort of thing. */ ! 204: ! 205: void ! 206: fancy_abort () ! 207: { ! 208: fatal ("Internal gcc abort."); ! 209: } ! 210: ! 211: int ! 212: main (argc, argv) ! 213: int argc; ! 214: char **argv; ! 215: { ! 216: rtx desc; ! 217: rtx dummy; ! 218: rtx *call_insns; ! 219: rtx *normal_insns; ! 220: rtx *insn_ptr; ! 221: FILE *infile; ! 222: register int c; ! 223: ! 224: obstack_init (rtl_obstack); ! 225: obstack_init (&call_obstack); ! 226: obstack_init (&normal_obstack); ! 227: ! 228: if (argc <= 1) ! 229: fatal ("No input file name."); ! 230: ! 231: infile = fopen (argv[1], "r"); ! 232: if (infile == 0) ! 233: { ! 234: perror (argv[1]); ! 235: exit (FATAL_EXIT_CODE); ! 236: } ! 237: ! 238: init_rtl (); ! 239: ! 240: printf ("/* Generated automatically by the program `genflags'\n\ ! 241: from the machine description file `md'. */\n\n"); ! 242: ! 243: /* Read the machine description. */ ! 244: ! 245: while (1) ! 246: { ! 247: c = read_skip_spaces (infile); ! 248: if (c == EOF) ! 249: break; ! 250: ungetc (c, infile); ! 251: ! 252: desc = read_rtx (infile); ! 253: if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) ! 254: gen_insn (desc); ! 255: } ! 256: ! 257: /* Print out the prototypes now. */ ! 258: dummy = (rtx)0; ! 259: obstack_grow (&call_obstack, &dummy, sizeof (rtx)); ! 260: call_insns = (rtx *) obstack_finish (&call_obstack); ! 261: ! 262: obstack_grow (&normal_obstack, &dummy, sizeof (rtx)); ! 263: normal_insns = (rtx *) obstack_finish (&normal_obstack); ! 264: ! 265: printf ("\n#ifndef NO_MD_PROTOTYPES\n"); ! 266: for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++) ! 267: gen_proto (*insn_ptr); ! 268: ! 269: printf ("\n#ifdef MD_CALL_PROTOTYPES\n"); ! 270: for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) ! 271: gen_proto (*insn_ptr); ! 272: ! 273: printf ("\n#else /* !MD_CALL_PROTOTYPES */\n"); ! 274: for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) ! 275: gen_nonproto (*insn_ptr); ! 276: ! 277: printf ("#endif /* !MD_CALL_PROTOTYPES */\n"); ! 278: printf ("\n#else /* NO_MD_PROTOTYPES */\n"); ! 279: for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++) ! 280: gen_nonproto (*insn_ptr); ! 281: ! 282: for (insn_ptr = call_insns; *insn_ptr; insn_ptr++) ! 283: gen_nonproto (*insn_ptr); ! 284: ! 285: printf ("#endif /* NO_MD_PROTOTYPES */\n"); ! 286: ! 287: fflush (stdout); ! 288: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); ! 289: /* NOTREACHED */ ! 290: return 0; ! 291: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.