|
|
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 "hconfig.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: extern rtx read_rtx (); ! 36: ! 37: /* flags to determine output of machine description dependent #define's. */ ! 38: static int max_recog_operands; /* Largest operand number seen. */ ! 39: static int max_dup_operands; /* Largest number of match_dup in any insn. */ ! 40: static int max_clobbers_per_insn; ! 41: static int register_constraint_flag; ! 42: static int have_cc0_flag; ! 43: static int have_cmove_flag; ! 44: static int have_lo_sum_flag; ! 45: ! 46: /* Maximum number of insns seen in a split. */ ! 47: static int max_insns_per_split = 1; ! 48: ! 49: static int clobbers_seen_this_insn; ! 50: static int dup_operands_seen_this_insn; ! 51: ! 52: char *xmalloc (); ! 53: static void fatal (); ! 54: void fancy_abort (); ! 55: ! 56: /* RECOG_P will be non-zero if this pattern was seen in a context where it will ! 57: be used to recognize, rather than just generate an insn. ! 58: ! 59: NON_PC_SET_SRC will be non-zero if this pattern was seen in a SET_SRC ! 60: of a SET whose destination is not (pc). */ ! 61: ! 62: static void ! 63: walk_insn_part (part, recog_p, non_pc_set_src) ! 64: rtx part; ! 65: int recog_p; ! 66: int non_pc_set_src; ! 67: { ! 68: register int i, j; ! 69: register RTX_CODE code; ! 70: register char *format_ptr; ! 71: ! 72: if (part == 0) ! 73: return; ! 74: ! 75: code = GET_CODE (part); ! 76: switch (code) ! 77: { ! 78: case CLOBBER: ! 79: clobbers_seen_this_insn++; ! 80: break; ! 81: ! 82: case MATCH_OPERAND: ! 83: if (XINT (part, 0) > max_recog_operands) ! 84: max_recog_operands = XINT (part, 0); ! 85: if (XSTR (part, 2) && *XSTR (part, 2)) ! 86: register_constraint_flag = 1; ! 87: return; ! 88: ! 89: case MATCH_OP_DUP: ! 90: case MATCH_PAR_DUP: ! 91: ++dup_operands_seen_this_insn; ! 92: case MATCH_SCRATCH: ! 93: case MATCH_PARALLEL: ! 94: case MATCH_OPERATOR: ! 95: if (XINT (part, 0) > max_recog_operands) ! 96: max_recog_operands = XINT (part, 0); ! 97: /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or ! 98: MATCH_PARALLEL. */ ! 99: break; ! 100: ! 101: case LABEL_REF: ! 102: if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND) ! 103: break; ! 104: return; ! 105: ! 106: case MATCH_DUP: ! 107: ++dup_operands_seen_this_insn; ! 108: if (XINT (part, 0) > max_recog_operands) ! 109: max_recog_operands = XINT (part, 0); ! 110: return; ! 111: ! 112: case CC0: ! 113: if (recog_p) ! 114: have_cc0_flag = 1; ! 115: return; ! 116: ! 117: case LO_SUM: ! 118: if (recog_p) ! 119: have_lo_sum_flag = 1; ! 120: return; ! 121: ! 122: case SET: ! 123: walk_insn_part (SET_DEST (part), 0, recog_p); ! 124: walk_insn_part (SET_SRC (part), recog_p, ! 125: GET_CODE (SET_DEST (part)) != PC); ! 126: return; ! 127: ! 128: case IF_THEN_ELSE: ! 129: /* Only consider this machine as having a conditional move if the ! 130: two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise, ! 131: we have some specific IF_THEN_ELSE construct (like the doz ! 132: instruction on the RS/6000) that can't be used in the general ! 133: context we want it for. */ ! 134: ! 135: if (recog_p && non_pc_set_src ! 136: && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND ! 137: && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND) ! 138: have_cmove_flag = 1; ! 139: break; ! 140: ! 141: case REG: case CONST_INT: case SYMBOL_REF: ! 142: case PC: ! 143: return; ! 144: } ! 145: ! 146: format_ptr = GET_RTX_FORMAT (GET_CODE (part)); ! 147: ! 148: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) ! 149: switch (*format_ptr++) ! 150: { ! 151: case 'e': ! 152: case 'u': ! 153: walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src); ! 154: break; ! 155: case 'E': ! 156: if (XVEC (part, i) != NULL) ! 157: for (j = 0; j < XVECLEN (part, i); j++) ! 158: walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src); ! 159: break; ! 160: } ! 161: } ! 162: ! 163: static void ! 164: gen_insn (insn) ! 165: rtx insn; ! 166: { ! 167: int i; ! 168: ! 169: /* Walk the insn pattern to gather the #define's status. */ ! 170: clobbers_seen_this_insn = 0; ! 171: dup_operands_seen_this_insn = 0; ! 172: if (XVEC (insn, 1) != 0) ! 173: for (i = 0; i < XVECLEN (insn, 1); i++) ! 174: walk_insn_part (XVECEXP (insn, 1, i), 1, 0); ! 175: ! 176: if (clobbers_seen_this_insn > max_clobbers_per_insn) ! 177: max_clobbers_per_insn = clobbers_seen_this_insn; ! 178: if (dup_operands_seen_this_insn > max_dup_operands) ! 179: max_dup_operands = dup_operands_seen_this_insn; ! 180: } ! 181: ! 182: /* Similar but scan a define_expand. */ ! 183: ! 184: static void ! 185: gen_expand (insn) ! 186: rtx insn; ! 187: { ! 188: int i; ! 189: ! 190: /* Walk the insn pattern to gather the #define's status. */ ! 191: ! 192: /* Note that we don't bother recording the number of MATCH_DUPs ! 193: that occur in a gen_expand, because only reload cares about that. */ ! 194: if (XVEC (insn, 1) != 0) ! 195: for (i = 0; i < XVECLEN (insn, 1); i++) ! 196: { ! 197: /* Compute the maximum SETs and CLOBBERS ! 198: in any one of the sub-insns; ! 199: don't sum across all of them. */ ! 200: clobbers_seen_this_insn = 0; ! 201: ! 202: walk_insn_part (XVECEXP (insn, 1, i), 0, 0); ! 203: ! 204: if (clobbers_seen_this_insn > max_clobbers_per_insn) ! 205: max_clobbers_per_insn = clobbers_seen_this_insn; ! 206: } ! 207: } ! 208: ! 209: /* Similar but scan a define_split. */ ! 210: ! 211: static void ! 212: gen_split (split) ! 213: rtx split; ! 214: { ! 215: int i; ! 216: ! 217: /* Look through the patterns that are matched ! 218: to compute the maximum operand number. */ ! 219: for (i = 0; i < XVECLEN (split, 0); i++) ! 220: walk_insn_part (XVECEXP (split, 0, i), 1, 0); ! 221: /* Look at the number of insns this insn could split into. */ ! 222: if (XVECLEN (split, 2) > max_insns_per_split) ! 223: max_insns_per_split = XVECLEN (split, 2); ! 224: } ! 225: ! 226: static void ! 227: gen_peephole (peep) ! 228: rtx peep; ! 229: { ! 230: int i; ! 231: ! 232: /* Look through the patterns that are matched ! 233: to compute the maximum operand number. */ ! 234: for (i = 0; i < XVECLEN (peep, 0); i++) ! 235: walk_insn_part (XVECEXP (peep, 0, i), 1, 0); ! 236: } ! 237: ! 238: char * ! 239: xmalloc (size) ! 240: unsigned size; ! 241: { ! 242: register char *val = (char *) malloc (size); ! 243: ! 244: if (val == 0) ! 245: fatal ("virtual memory exhausted"); ! 246: ! 247: return val; ! 248: } ! 249: ! 250: char * ! 251: xrealloc (ptr, size) ! 252: char *ptr; ! 253: unsigned size; ! 254: { ! 255: char *result = (char *) realloc (ptr, size); ! 256: if (!result) ! 257: fatal ("virtual memory exhausted"); ! 258: return result; ! 259: } ! 260: ! 261: static void ! 262: fatal (s, a1, a2) ! 263: char *s; ! 264: { ! 265: fprintf (stderr, "genconfig: "); ! 266: fprintf (stderr, s, a1, a2); ! 267: fprintf (stderr, "\n"); ! 268: exit (FATAL_EXIT_CODE); ! 269: } ! 270: ! 271: /* More 'friendly' abort that prints the line and file. ! 272: config.h can #define abort fancy_abort if you like that sort of thing. */ ! 273: ! 274: void ! 275: fancy_abort () ! 276: { ! 277: fatal ("Internal gcc abort."); ! 278: } ! 279: ! 280: int ! 281: main (argc, argv) ! 282: int argc; ! 283: char **argv; ! 284: { ! 285: rtx desc; ! 286: FILE *infile; ! 287: register int c; ! 288: ! 289: obstack_init (rtl_obstack); ! 290: ! 291: if (argc <= 1) ! 292: fatal ("No input file name."); ! 293: ! 294: infile = fopen (argv[1], "r"); ! 295: if (infile == 0) ! 296: { ! 297: perror (argv[1]); ! 298: exit (FATAL_EXIT_CODE); ! 299: } ! 300: ! 301: init_rtl (); ! 302: ! 303: printf ("/* Generated automatically by the program `genconfig'\n\ ! 304: from the machine description file `md'. */\n\n"); ! 305: ! 306: /* Allow at least 10 operands for the sake of asm constructs. */ ! 307: max_recog_operands = 9; /* We will add 1 later. */ ! 308: max_dup_operands = 1; ! 309: ! 310: /* Read the machine description. */ ! 311: ! 312: while (1) ! 313: { ! 314: c = read_skip_spaces (infile); ! 315: if (c == EOF) ! 316: break; ! 317: ungetc (c, infile); ! 318: ! 319: desc = read_rtx (infile); ! 320: if (GET_CODE (desc) == DEFINE_INSN) ! 321: gen_insn (desc); ! 322: if (GET_CODE (desc) == DEFINE_EXPAND) ! 323: gen_expand (desc); ! 324: if (GET_CODE (desc) == DEFINE_SPLIT) ! 325: gen_split (desc); ! 326: if (GET_CODE (desc) == DEFINE_PEEPHOLE) ! 327: gen_peephole (desc); ! 328: } ! 329: ! 330: printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1); ! 331: ! 332: printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands); ! 333: ! 334: /* This is conditionally defined, in case the user writes code which emits ! 335: more splits than we can readily see (and knows s/he does it). */ ! 336: printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n", ! 337: max_insns_per_split); ! 338: ! 339: if (register_constraint_flag) ! 340: printf ("#define REGISTER_CONSTRAINTS\n"); ! 341: ! 342: if (have_cc0_flag) ! 343: printf ("#define HAVE_cc0\n"); ! 344: ! 345: if (have_cmove_flag) ! 346: printf ("#define HAVE_conditional_move\n"); ! 347: ! 348: if (have_lo_sum_flag) ! 349: printf ("#define HAVE_lo_sum\n"); ! 350: ! 351: fflush (stdout); ! 352: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); ! 353: /* NOTREACHED */ ! 354: return 0; ! 355: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.