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