|
|
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>
1.1.1.2 ! root 23: #include "config.h"
1.1 root 24: #include "rtl.h"
1.1.1.2 ! root 25: #include "obstack.h"
1.1 root 26:
27: struct obstack obstack;
1.1.1.2 ! root 28: struct obstack *rtl_obstack = &obstack;
1.1 root 29:
30: #define obstack_chunk_alloc xmalloc
31: #define obstack_chunk_free free
32: extern int xmalloc ();
33: extern void free ();
34:
1.1.1.2 ! root 35: void walk_rtx ();
! 36: void print_path ();
1.1 root 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
1.1.1.2 ! root 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. */
1.1 root 53:
54: struct link
55: {
56: struct link *next;
57: int pos;
1.1.1.2 ! root 58: int vecelt;
1.1 root 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. */
1.1.1.2 ! root 73: printf ("VOID\nextract_%d (insn)\n rtx insn;\n", insn_code_number);
1.1 root 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;
1.1.1.2 ! root 86: link.pos = 0;
! 87: link.vecelt = i;
1.1 root 88: walk_rtx (XVECEXP (insn, 1, i), &link);
89: }
90: printf ("}\n\n");
91: }
92:
1.1.1.2 ! root 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
1.1 root 112: walk_rtx (x, path)
113: rtx x;
114: struct link *path;
115: {
1.1.1.2 ! root 116: register RTX_CODE code;
1.1 root 117: register int i;
118: register int len;
119: register char *fmt;
120: struct link link;
121:
1.1.1.2 ! root 122: if (x == 0)
! 123: return;
! 124:
! 125: code = GET_CODE (x);
! 126:
1.1 root 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;
1.1.1.2 ! root 156: link.vecelt = -1;
1.1 root 157: fmt = GET_RTX_FORMAT (code);
158: len = GET_RTX_LENGTH (code);
159: for (i = 0; i < len; i++)
1.1.1.2 ! root 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: }
1.1 root 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:
1.1.1.2 ! root 182: void
1.1 root 183: print_path (path)
184: struct link *path;
185: {
186: if (path == 0)
187: printf ("insn");
1.1.1.2 ! root 188: else if (path->vecelt >= 0)
1.1 root 189: {
190: printf ("XVECEXP (");
191: print_path (path->next);
1.1.1.2 ! root 192: printf (", %d, %d)", path->pos, path->vecelt);
1.1 root 193: }
194: else
195: {
196: printf ("XEXP (");
197: print_path (path->next);
198: printf (", %d)", path->pos);
199: }
200: }
201:
1.1.1.2 ! root 202: int
1.1 root 203: xmalloc (size)
204: {
205: register int val = malloc (size);
206:
207: if (val == 0)
1.1.1.2 ! root 208: fatal ("virtual memory exhausted");
1.1 root 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)
1.1.1.2 ! root 219: fatal ("virtual memory exhausted");
1.1 root 220: return result;
221: }
222:
223: void
224: fatal (s, a1, a2)
225: {
1.1.1.2 ! root 226: fprintf (stderr, "genextract: ");
1.1 root 227: fprintf (stderr, s, a1, a2);
228: fprintf (stderr, "\n");
1.1.1.2 ! root 229: exit (FATAL_EXIT_CODE);
1.1 root 230: }
231:
1.1.1.2 ! root 232: int
1.1 root 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:
1.1.1.2 ! root 242: obstack_init (rtl_obstack);
1.1 root 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]);
1.1.1.2 ! root 251: exit (FATAL_EXIT_CODE);
1.1 root 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:
1.1.1.2 ! root 264: printf ("#include \"config.h\"\n");
1.1 root 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:
1.1.1.2 ! root 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:
1.1 root 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);
1.1.1.2 ! root 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: }
1.1 root 303: }
304:
1.1.1.2 ! root 305: printf ("VOID (*insn_extract_fn[]) () =\n{ ");
1.1 root 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");
1.1.1.2 ! root 320:
! 321: fflush (stdout);
! 322: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1.1 root 323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.