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