|
|
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 "rtl.h" ! 24: #include <obstack.h> ! 25: ! 26: struct obstack obstack; ! 27: struct obstack *current_obstack = &obstack; ! 28: ! 29: #define obstack_chunk_alloc xmalloc ! 30: #define obstack_chunk_free free ! 31: extern int xmalloc (); ! 32: extern void free (); ! 33: ! 34: void fatal (); ! 35: ! 36: /* Number instruction patterns handled, starting at 0 for first one. */ ! 37: ! 38: int insn_code_number; ! 39: ! 40: /* Number the occurrences of MATCH_DUP in each instruction, ! 41: starting at 0 for the first occurrence. */ ! 42: ! 43: int dup_count; ! 44: ! 45: /* While tree-walking an instruction pattern, we keep a chain ! 46: of these `struct link's to record how to get down to the ! 47: current position. In each one, POS is the operand number ! 48: or vector element number, and VEC is nonzero for a vector. */ ! 49: ! 50: struct link ! 51: { ! 52: struct link *next; ! 53: int pos; ! 54: int vec; ! 55: }; ! 56: ! 57: void ! 58: gen_insn (insn) ! 59: rtx insn; ! 60: { ! 61: register int i; ! 62: ! 63: dup_count = 0; ! 64: ! 65: /* Output the function name and argument declaration. */ ! 66: /* It would be cleaner to make `int' the return type ! 67: but 4.2 vax compiler doesn't accept that in the array ! 68: that these functions are supposed to go in. */ ! 69: printf ("int\nextract_%d (insn)\n rtx insn;\n", insn_code_number); ! 70: printf ("{\n"); ! 71: ! 72: /* Walk the insn's pattern, remembering at all times the path ! 73: down to the walking point. */ ! 74: ! 75: if (XVECLEN (insn, 1) == 1) ! 76: walk_rtx (XVECEXP (insn, 1, 0), 0); ! 77: else ! 78: for (i = XVECLEN (insn, 1) - 1; i >= 0; i--) ! 79: { ! 80: struct link link; ! 81: link.next = 0; ! 82: link.pos = i; ! 83: link.vec = 1; ! 84: walk_rtx (XVECEXP (insn, 1, i), &link); ! 85: } ! 86: printf ("}\n\n"); ! 87: } ! 88: ! 89: walk_rtx (x, path) ! 90: rtx x; ! 91: struct link *path; ! 92: { ! 93: register RTX_CODE code = GET_CODE (x); ! 94: register int i; ! 95: register int len; ! 96: register char *fmt; ! 97: struct link link; ! 98: ! 99: switch (code) ! 100: { ! 101: case PC: ! 102: case CC0: ! 103: case CONST_INT: ! 104: case SYMBOL_REF: ! 105: return; ! 106: ! 107: case MATCH_OPERAND: ! 108: printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &", ! 109: XINT (x, 0), XINT (x, 0)); ! 110: print_path (path); ! 111: printf (");\n"); ! 112: break; ! 113: ! 114: case MATCH_DUP: ! 115: printf (" recog_dup_loc[%d] = &", dup_count); ! 116: print_path (path); ! 117: printf (";\n"); ! 118: printf (" recog_dup_num[%d] = %d;\n", dup_count, XINT (x, 0)); ! 119: dup_count++; ! 120: break; ! 121: ! 122: case ADDRESS: ! 123: walk_rtx (XEXP (x, 0), path); ! 124: return; ! 125: } ! 126: ! 127: link.next = path; ! 128: link.vec = 0; ! 129: fmt = GET_RTX_FORMAT (code); ! 130: len = GET_RTX_LENGTH (code); ! 131: for (i = 0; i < len; i++) ! 132: if (fmt[i] == 'e' || fmt[i] == 'u') ! 133: { ! 134: link.pos = i; ! 135: walk_rtx (XEXP (x, i), &link); ! 136: } ! 137: } ! 138: ! 139: /* Given a PATH, representing a path down the instruction's ! 140: pattern from the root to a certain point, output code to ! 141: evaluate to the rtx at that point. */ ! 142: ! 143: print_path (path) ! 144: struct link *path; ! 145: { ! 146: if (path == 0) ! 147: printf ("insn"); ! 148: else if (path->vec) ! 149: { ! 150: printf ("XVECEXP ("); ! 151: print_path (path->next); ! 152: printf (", 0, %d)", path->pos); ! 153: } ! 154: else ! 155: { ! 156: printf ("XEXP ("); ! 157: print_path (path->next); ! 158: printf (", %d)", path->pos); ! 159: } ! 160: } ! 161: ! 162: xmalloc (size) ! 163: { ! 164: register int val = malloc (size); ! 165: ! 166: if (val == 0) ! 167: abort (); ! 168: ! 169: return val; ! 170: } ! 171: ! 172: int ! 173: xrealloc (ptr, size) ! 174: char *ptr; ! 175: int size; ! 176: { ! 177: int result = realloc (ptr, size); ! 178: if (!result) ! 179: abort (); ! 180: return result; ! 181: } ! 182: ! 183: void ! 184: fatal (s, a1, a2) ! 185: { ! 186: fprintf (stderr, "genemit: "); ! 187: fprintf (stderr, s, a1, a2); ! 188: fprintf (stderr, "\n"); ! 189: exit (1); ! 190: } ! 191: ! 192: main (argc, argv) ! 193: int argc; ! 194: char **argv; ! 195: { ! 196: rtx desc; ! 197: FILE *infile; ! 198: extern rtx read_rtx (); ! 199: register int c, i; ! 200: ! 201: obstack_begin (current_obstack, 4060); ! 202: ! 203: if (argc <= 1) ! 204: fatal ("No input file name."); ! 205: ! 206: infile = fopen (argv[1], "r"); ! 207: if (infile == 0) ! 208: { ! 209: perror (argv[1]); ! 210: exit (1); ! 211: } ! 212: ! 213: init_rtl (); ! 214: ! 215: /* Assign sequential codes to all entries in the machine description ! 216: in parallel with the tables in insn-output.c. */ ! 217: ! 218: insn_code_number = 0; ! 219: ! 220: printf ("/* Generated automatically by the program `genextract'\n\ ! 221: from the machine description file `md'. */\n\n"); ! 222: ! 223: printf ("#include \"rtl.h\"\n\n"); ! 224: ! 225: printf ("extern rtx recog_operand[];\n"); ! 226: printf ("extern rtx *recog_operand_loc[];\n"); ! 227: printf ("extern rtx *recog_dup_loc[];\n"); ! 228: printf ("extern char recog_dup_num[];\n\n"); ! 229: ! 230: /* Read the machine description. */ ! 231: ! 232: while (1) ! 233: { ! 234: c = read_skip_spaces (infile); ! 235: if (c == EOF) ! 236: break; ! 237: ungetc (c, infile); ! 238: ! 239: desc = read_rtx (infile); ! 240: gen_insn (desc); ! 241: ++insn_code_number; ! 242: } ! 243: ! 244: printf ("int (*insn_extract_fn[]) () =\n{ "); ! 245: for (i = 0; i < insn_code_number; i++) ! 246: { ! 247: if (i % 4 != 0) ! 248: printf (", "); ! 249: else if (i != 0) ! 250: printf (",\n "); ! 251: printf ("extract_%d", i); ! 252: } ! 253: printf ("\n};\n\n"); ! 254: ! 255: printf ("void\ninsn_extract (insn)\n"); ! 256: printf (" rtx insn;\n"); ! 257: printf ("{\n if (INSN_CODE (insn) == -1) abort ();\n"); ! 258: printf (" (*insn_extract_fn[INSN_CODE (insn)]) (PATTERN (insn));\n}\n"); ! 259: return 0; ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.