|
|
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.