|
|
1.1 ! root 1: /* Generate code from machine description to extract operands from insn 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 walk_rtx (); ! 36: void print_path (); ! 37: void fatal (); ! 38: ! 39: /* Number instruction patterns handled, starting at 0 for first one. */ ! 40: ! 41: int insn_code_number; ! 42: ! 43: /* Number the occurrences of MATCH_DUP in each instruction, ! 44: starting at 0 for the first occurrence. */ ! 45: ! 46: int dup_count; ! 47: ! 48: /* While tree-walking an instruction pattern, we keep a chain ! 49: of these `struct link's to record how to get down to the ! 50: current position. In each one, POS is the operand number, ! 51: and if the operand is a vector VEC is the element number. ! 52: VEC is -1 if the operand is not a vector. */ ! 53: ! 54: struct link ! 55: { ! 56: struct link *next; ! 57: int pos; ! 58: int vecelt; ! 59: }; ! 60: ! 61: void ! 62: gen_insn (insn) ! 63: rtx insn; ! 64: { ! 65: register int i; ! 66: ! 67: dup_count = 0; ! 68: ! 69: /* Output the function name and argument declaration. */ ! 70: /* It would be cleaner to make `int' the return type ! 71: but 4.2 vax compiler doesn't accept that in the array ! 72: that these functions are supposed to go in. */ ! 73: printf ("VOID\nextract_%d (insn)\n rtx insn;\n", insn_code_number); ! 74: printf ("{\n"); ! 75: ! 76: /* Walk the insn's pattern, remembering at all times the path ! 77: down to the walking point. */ ! 78: ! 79: if (XVECLEN (insn, 1) == 1) ! 80: walk_rtx (XVECEXP (insn, 1, 0), 0); ! 81: else ! 82: for (i = XVECLEN (insn, 1) - 1; i >= 0; i--) ! 83: { ! 84: struct link link; ! 85: link.next = 0; ! 86: link.pos = 0; ! 87: link.vecelt = i; ! 88: walk_rtx (XVECEXP (insn, 1, i), &link); ! 89: } ! 90: printf ("}\n\n"); ! 91: } ! 92: ! 93: /* Like gen_insn but handles `define_peephole'. */ ! 94: ! 95: void ! 96: gen_peephole (peep) ! 97: rtx peep; ! 98: { ! 99: /* Output the function name and argument declaration. */ ! 100: printf ("VOID\nextract_%d (insn)\n rtx insn;\n", insn_code_number); ! 101: printf ("{\n"); ! 102: /* The vector in the insn says how many operands it has. ! 103: And all it contains are operands. In fact, the vector was ! 104: created just for the sake of this function. */ ! 105: printf ("\ ! 106: bcopy (&XVECEXP (insn, 0, 0), recog_operand,\ ! 107: UNITS_PER_WORD * XVECLEN (insn, 0));\n"); ! 108: printf ("}\n\n"); ! 109: } ! 110: ! 111: void ! 112: walk_rtx (x, path) ! 113: rtx x; ! 114: struct link *path; ! 115: { ! 116: register RTX_CODE code; ! 117: register int i; ! 118: register int len; ! 119: register char *fmt; ! 120: struct link link; ! 121: ! 122: if (x == 0) ! 123: return; ! 124: ! 125: code = GET_CODE (x); ! 126: ! 127: switch (code) ! 128: { ! 129: case PC: ! 130: case CC0: ! 131: case CONST_INT: ! 132: case SYMBOL_REF: ! 133: return; ! 134: ! 135: case MATCH_OPERAND: ! 136: printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &", ! 137: XINT (x, 0), XINT (x, 0)); ! 138: print_path (path); ! 139: printf (");\n"); ! 140: break; ! 141: ! 142: case MATCH_DUP: ! 143: printf (" recog_dup_loc[%d] = &", dup_count); ! 144: print_path (path); ! 145: printf (";\n"); ! 146: printf (" recog_dup_num[%d] = %d;\n", dup_count, XINT (x, 0)); ! 147: dup_count++; ! 148: break; ! 149: ! 150: case ADDRESS: ! 151: walk_rtx (XEXP (x, 0), path); ! 152: return; ! 153: } ! 154: ! 155: link.next = path; ! 156: link.vecelt = -1; ! 157: fmt = GET_RTX_FORMAT (code); ! 158: len = GET_RTX_LENGTH (code); ! 159: for (i = 0; i < len; i++) ! 160: { ! 161: link.pos = i; ! 162: if (fmt[i] == 'e' || fmt[i] == 'u') ! 163: { ! 164: walk_rtx (XEXP (x, i), &link); ! 165: } ! 166: else if (fmt[i] == 'E') ! 167: { ! 168: int j; ! 169: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 170: { ! 171: link.vecelt = j; ! 172: walk_rtx (XVECEXP (x, i, j), &link); ! 173: } ! 174: } ! 175: } ! 176: } ! 177: ! 178: /* Given a PATH, representing a path down the instruction's ! 179: pattern from the root to a certain point, output code to ! 180: evaluate to the rtx at that point. */ ! 181: ! 182: void ! 183: print_path (path) ! 184: struct link *path; ! 185: { ! 186: if (path == 0) ! 187: printf ("insn"); ! 188: else if (path->vecelt >= 0) ! 189: { ! 190: printf ("XVECEXP ("); ! 191: print_path (path->next); ! 192: printf (", %d, %d)", path->pos, path->vecelt); ! 193: } ! 194: else ! 195: { ! 196: printf ("XEXP ("); ! 197: print_path (path->next); ! 198: printf (", %d)", path->pos); ! 199: } ! 200: } ! 201: ! 202: int ! 203: xmalloc (size) ! 204: { ! 205: register int val = malloc (size); ! 206: ! 207: if (val == 0) ! 208: fatal ("virtual memory exhausted"); ! 209: return val; ! 210: } ! 211: ! 212: int ! 213: xrealloc (ptr, size) ! 214: char *ptr; ! 215: int size; ! 216: { ! 217: int result = realloc (ptr, size); ! 218: if (!result) ! 219: fatal ("virtual memory exhausted"); ! 220: return result; ! 221: } ! 222: ! 223: void ! 224: fatal (s, a1, a2) ! 225: { ! 226: fprintf (stderr, "genextract: "); ! 227: fprintf (stderr, s, a1, a2); ! 228: fprintf (stderr, "\n"); ! 229: exit (FATAL_EXIT_CODE); ! 230: } ! 231: ! 232: int ! 233: main (argc, argv) ! 234: int argc; ! 235: char **argv; ! 236: { ! 237: rtx desc; ! 238: FILE *infile; ! 239: extern rtx read_rtx (); ! 240: register int c, i; ! 241: ! 242: obstack_init (rtl_obstack); ! 243: ! 244: if (argc <= 1) ! 245: fatal ("No input file name."); ! 246: ! 247: infile = fopen (argv[1], "r"); ! 248: if (infile == 0) ! 249: { ! 250: perror (argv[1]); ! 251: exit (FATAL_EXIT_CODE); ! 252: } ! 253: ! 254: init_rtl (); ! 255: ! 256: /* Assign sequential codes to all entries in the machine description ! 257: in parallel with the tables in insn-output.c. */ ! 258: ! 259: insn_code_number = 0; ! 260: ! 261: printf ("/* Generated automatically by the program `genextract'\n\ ! 262: from the machine description file `md'. */\n\n"); ! 263: ! 264: printf ("#include \"config.h\"\n"); ! 265: printf ("#include \"rtl.h\"\n\n"); ! 266: ! 267: printf ("extern rtx recog_operand[];\n"); ! 268: printf ("extern rtx *recog_operand_loc[];\n"); ! 269: printf ("extern rtx *recog_dup_loc[];\n"); ! 270: printf ("extern char recog_dup_num[];\n\n"); ! 271: ! 272: /* The extractor functions really should return `void'; ! 273: but old C compilers don't seem to be able to handle the array ! 274: definition if `void' is used. So use `int' in non-ANSI C compilers. */ ! 275: ! 276: printf ("#ifdef __STDC__\n#define VOID void\n#else\n#define VOID int\n#endif\n\n"); ! 277: ! 278: /* Read the machine description. */ ! 279: ! 280: while (1) ! 281: { ! 282: c = read_skip_spaces (infile); ! 283: if (c == EOF) ! 284: break; ! 285: ungetc (c, infile); ! 286: ! 287: desc = read_rtx (infile); ! 288: if (GET_CODE (desc) == DEFINE_INSN) ! 289: { ! 290: gen_insn (desc); ! 291: ++insn_code_number; ! 292: } ! 293: if (GET_CODE (desc) == DEFINE_PEEPHOLE) ! 294: { ! 295: gen_peephole (desc); ! 296: ++insn_code_number; ! 297: } ! 298: if (GET_CODE (desc) == DEFINE_EXPAND) ! 299: { ! 300: printf ("VOID extract_%d () {}\n\n", insn_code_number); ! 301: ++insn_code_number; ! 302: } ! 303: } ! 304: ! 305: printf ("VOID (*insn_extract_fn[]) () =\n{ "); ! 306: for (i = 0; i < insn_code_number; i++) ! 307: { ! 308: if (i % 4 != 0) ! 309: printf (", "); ! 310: else if (i != 0) ! 311: printf (",\n "); ! 312: printf ("extract_%d", i); ! 313: } ! 314: printf ("\n};\n\n"); ! 315: ! 316: printf ("void\ninsn_extract (insn)\n"); ! 317: printf (" rtx insn;\n"); ! 318: printf ("{\n if (INSN_CODE (insn) == -1) abort ();\n"); ! 319: printf (" (*insn_extract_fn[INSN_CODE (insn)]) (PATTERN (insn));\n}\n"); ! 320: ! 321: fflush (stdout); ! 322: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); ! 323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.