|
|
1.1 ! root 1: /* Generate from machine description: ! 2: ! 3: - some #define configuration flags. ! 4: Copyright (C) 1987, 1991 Free Software Foundation, Inc. ! 5: ! 6: This file is part of GNU CC. ! 7: ! 8: GNU CC is free software; you can redistribute it and/or modify ! 9: it under the terms of the GNU General Public License as published by ! 10: the Free Software Foundation; either version 2, or (at your option) ! 11: any later version. ! 12: ! 13: GNU CC is distributed in the hope that it will be useful, ! 14: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: GNU General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with GNU CC; see the file COPYING. If not, write to ! 20: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 21: ! 22: ! 23: #include <stdio.h> ! 24: #include "config.h" ! 25: #include "rtl.h" ! 26: #include "obstack.h" ! 27: ! 28: static struct obstack obstack; ! 29: struct obstack *rtl_obstack = &obstack; ! 30: ! 31: #define obstack_chunk_alloc xmalloc ! 32: #define obstack_chunk_free free ! 33: ! 34: extern void free (); ! 35: ! 36: /* flags to determine output of machine description dependent #define's. */ ! 37: static int max_recog_operands; ! 38: static int max_dup_operands; ! 39: static int max_clobbers_per_insn; ! 40: static int register_constraint_flag; ! 41: static int have_cc0_flag; ! 42: static int have_lo_sum_flag; ! 43: ! 44: /* Maximum number of insns seen in a split. */ ! 45: static int max_insns_per_split = 1; ! 46: ! 47: static int clobbers_seen_this_insn; ! 48: static int dup_operands_seen_this_insn; ! 49: ! 50: char *xmalloc (); ! 51: static void fatal (); ! 52: void fancy_abort (); ! 53: ! 54: /* RECOG_P will be non-zero if this pattern was seen in a context where it will ! 55: be used to recognize, rather than just generate an insn. */ ! 56: ! 57: static void ! 58: walk_insn_part (part, recog_p) ! 59: rtx part; ! 60: { ! 61: register int i, j; ! 62: register RTX_CODE code; ! 63: register char *format_ptr; ! 64: ! 65: if (part == 0) ! 66: return; ! 67: ! 68: code = GET_CODE (part); ! 69: switch (code) ! 70: { ! 71: case CLOBBER: ! 72: clobbers_seen_this_insn++; ! 73: break; ! 74: ! 75: case MATCH_OPERAND: ! 76: if (XINT (part, 0) > max_recog_operands) ! 77: max_recog_operands = XINT (part, 0); ! 78: if (XSTR (part, 2) && *XSTR (part, 2)) ! 79: register_constraint_flag = 1; ! 80: return; ! 81: ! 82: case MATCH_OP_DUP: ! 83: ++dup_operands_seen_this_insn; ! 84: case MATCH_SCRATCH: ! 85: case MATCH_PARALLEL: ! 86: case MATCH_OPERATOR: ! 87: if (XINT (part, 0) > max_recog_operands) ! 88: max_recog_operands = XINT (part, 0); ! 89: /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or ! 90: MATCH_PARALLEL. */ ! 91: break; ! 92: ! 93: case LABEL_REF: ! 94: if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND) ! 95: break; ! 96: return; ! 97: ! 98: case MATCH_DUP: ! 99: ++dup_operands_seen_this_insn; ! 100: if (XINT (part, 0) > max_recog_operands) ! 101: max_recog_operands = XINT (part, 0); ! 102: return; ! 103: ! 104: case CC0: ! 105: if (recog_p) ! 106: have_cc0_flag = 1; ! 107: return; ! 108: ! 109: case LO_SUM: ! 110: if (recog_p) ! 111: have_lo_sum_flag = 1; ! 112: return; ! 113: ! 114: case REG: case CONST_INT: case SYMBOL_REF: ! 115: case PC: ! 116: return; ! 117: } ! 118: ! 119: format_ptr = GET_RTX_FORMAT (GET_CODE (part)); ! 120: ! 121: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) ! 122: switch (*format_ptr++) ! 123: { ! 124: case 'e': ! 125: case 'u': ! 126: walk_insn_part (XEXP (part, i), recog_p); ! 127: break; ! 128: case 'E': ! 129: if (XVEC (part, i) != NULL) ! 130: for (j = 0; j < XVECLEN (part, i); j++) ! 131: walk_insn_part (XVECEXP (part, i, j), recog_p); ! 132: break; ! 133: } ! 134: } ! 135: ! 136: static void ! 137: gen_insn (insn) ! 138: rtx insn; ! 139: { ! 140: int i; ! 141: ! 142: /* Walk the insn pattern to gather the #define's status. */ ! 143: clobbers_seen_this_insn = 0; ! 144: dup_operands_seen_this_insn = 0; ! 145: if (XVEC (insn, 1) != 0) ! 146: for (i = 0; i < XVECLEN (insn, 1); i++) ! 147: walk_insn_part (XVECEXP (insn, 1, i), 1); ! 148: ! 149: if (clobbers_seen_this_insn > max_clobbers_per_insn) ! 150: max_clobbers_per_insn = clobbers_seen_this_insn; ! 151: if (dup_operands_seen_this_insn > max_dup_operands) ! 152: max_dup_operands = dup_operands_seen_this_insn; ! 153: } ! 154: ! 155: /* Similar but scan a define_expand. */ ! 156: ! 157: static void ! 158: gen_expand (insn) ! 159: rtx insn; ! 160: { ! 161: int i; ! 162: ! 163: /* Walk the insn pattern to gather the #define's status. */ ! 164: ! 165: /* Note that we don't bother recording the number of MATCH_DUPs ! 166: that occur in a gen_expand, because only reload cares about that. */ ! 167: if (XVEC (insn, 1) != 0) ! 168: for (i = 0; i < XVECLEN (insn, 1); i++) ! 169: { ! 170: /* Compute the maximum SETs and CLOBBERS ! 171: in any one of the sub-insns; ! 172: don't sum across all of them. */ ! 173: clobbers_seen_this_insn = 0; ! 174: ! 175: walk_insn_part (XVECEXP (insn, 1, i), 0); ! 176: ! 177: if (clobbers_seen_this_insn > max_clobbers_per_insn) ! 178: max_clobbers_per_insn = clobbers_seen_this_insn; ! 179: } ! 180: } ! 181: ! 182: /* Similar but scan a define_split. */ ! 183: ! 184: static void ! 185: gen_split (split) ! 186: rtx split; ! 187: { ! 188: int i; ! 189: ! 190: /* Look through the patterns that are matched ! 191: to compute the maximum operand number. */ ! 192: for (i = 0; i < XVECLEN (split, 0); i++) ! 193: walk_insn_part (XVECEXP (split, 0, i), 1); ! 194: /* Look at the number of insns this insn could split into. */ ! 195: if (XVECLEN (split, 2) > max_insns_per_split) ! 196: max_insns_per_split = XVECLEN (split, 2); ! 197: } ! 198: ! 199: static void ! 200: gen_peephole (peep) ! 201: rtx peep; ! 202: { ! 203: int i; ! 204: ! 205: /* Look through the patterns that are matched ! 206: to compute the maximum operand number. */ ! 207: for (i = 0; i < XVECLEN (peep, 0); i++) ! 208: walk_insn_part (XVECEXP (peep, 0, i), 1); ! 209: } ! 210: ! 211: char * ! 212: xmalloc (size) ! 213: unsigned size; ! 214: { ! 215: register char *val = (char *) malloc (size); ! 216: ! 217: if (val == 0) ! 218: fatal ("virtual memory exhausted"); ! 219: ! 220: return val; ! 221: } ! 222: ! 223: char * ! 224: xrealloc (ptr, size) ! 225: char *ptr; ! 226: unsigned size; ! 227: { ! 228: char *result = (char *) realloc (ptr, size); ! 229: if (!result) ! 230: fatal ("virtual memory exhausted"); ! 231: return result; ! 232: } ! 233: ! 234: static void ! 235: fatal (s, a1, a2) ! 236: char *s; ! 237: { ! 238: fprintf (stderr, "genconfig: "); ! 239: fprintf (stderr, s, a1, a2); ! 240: fprintf (stderr, "\n"); ! 241: exit (FATAL_EXIT_CODE); ! 242: } ! 243: ! 244: /* More 'friendly' abort that prints the line and file. ! 245: config.h can #define abort fancy_abort if you like that sort of thing. */ ! 246: ! 247: void ! 248: fancy_abort () ! 249: { ! 250: fatal ("Internal gcc abort."); ! 251: } ! 252: ! 253: int ! 254: main (argc, argv) ! 255: int argc; ! 256: char **argv; ! 257: { ! 258: rtx desc; ! 259: FILE *infile; ! 260: extern rtx read_rtx (); ! 261: register int c; ! 262: ! 263: obstack_init (rtl_obstack); ! 264: ! 265: if (argc <= 1) ! 266: fatal ("No input file name."); ! 267: ! 268: infile = fopen (argv[1], "r"); ! 269: if (infile == 0) ! 270: { ! 271: perror (argv[1]); ! 272: exit (FATAL_EXIT_CODE); ! 273: } ! 274: ! 275: init_rtl (); ! 276: ! 277: printf ("/* Generated automatically by the program `genconfig'\n\ ! 278: from the machine description file `md'. */\n\n"); ! 279: ! 280: /* Allow at least 10 operands for the sake of asm constructs. */ ! 281: max_recog_operands = 10; ! 282: max_dup_operands = 1; ! 283: ! 284: /* Read the machine description. */ ! 285: ! 286: while (1) ! 287: { ! 288: c = read_skip_spaces (infile); ! 289: if (c == EOF) ! 290: break; ! 291: ungetc (c, infile); ! 292: ! 293: desc = read_rtx (infile); ! 294: if (GET_CODE (desc) == DEFINE_INSN) ! 295: gen_insn (desc); ! 296: if (GET_CODE (desc) == DEFINE_EXPAND) ! 297: gen_expand (desc); ! 298: if (GET_CODE (desc) == DEFINE_SPLIT) ! 299: gen_split (desc); ! 300: if (GET_CODE (desc) == DEFINE_PEEPHOLE) ! 301: gen_peephole (desc); ! 302: } ! 303: ! 304: printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands); ! 305: ! 306: printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands); ! 307: ! 308: /* This is conditionally defined, in case the user writes code which emits ! 309: more splits than we can readily see (and knows s/he does it). */ ! 310: printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n", ! 311: max_insns_per_split); ! 312: ! 313: if (register_constraint_flag) ! 314: printf ("#define REGISTER_CONSTRAINTS\n"); ! 315: ! 316: if (have_cc0_flag) ! 317: printf ("#define HAVE_cc0\n"); ! 318: ! 319: if (have_lo_sum_flag) ! 320: printf ("#define HAVE_lo_sum\n"); ! 321: ! 322: fflush (stdout); ! 323: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); ! 324: /* NOTREACHED */ ! 325: return 0; ! 326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.