]> gcc.gnu.org Git - gcc.git/blob - gcc/gensupport.c
gensupport.c: New file.
[gcc.git] / gcc / gensupport.c
1 /* Read machine descriptions, return top level rtx for use by the
2 various generation passes.
3
4 Copyright (C) 2000 Free Software Foundation, Inc.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22
23 #include "hconfig.h"
24 #include "system.h"
25 #include "rtl.h"
26 #include "errors.h"
27 #include "gensupport.h"
28
29 static FILE *input_file;
30
31 static int sequence_num;
32
33 struct queue_elem {
34 rtx data;
35 struct queue_elem *next;
36 };
37
38 static struct queue_elem *rtx_ready_queue;
39
40 /* Recursively remove constraints from an rtx. */
41
42 static void
43 remove_constraints (part)
44 rtx part;
45 {
46 register int i, j;
47 register const char *format_ptr;
48
49 if (part == 0)
50 return;
51
52 if (GET_CODE (part) == MATCH_OPERAND)
53 XSTR (part, 2) = "";
54 else if (GET_CODE (part) == MATCH_SCRATCH)
55 XSTR (part, 1) = "";
56
57 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
58
59 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
60 switch (*format_ptr++)
61 {
62 case 'e':
63 case 'u':
64 remove_constraints (XEXP (part, i));
65 break;
66 case 'E':
67 if (XVEC (part, i) != NULL)
68 for (j = 0; j < XVECLEN (part, i); j++)
69 remove_constraints (XVECEXP (part, i, j));
70 break;
71 }
72 }
73
74 /* Handle any synthetic top level rtx, i.e. anything except:
75 DEFINE_INSN
76 DEFINE_EXPAND
77 DEFINE_SPLIT
78 DEFINE_PEEPHOLE
79 DEFINE_PEEPHOLE2
80 DEFINE_ATTRIBUTE
81 DEFINE_FUNCTION_UNIT
82 DEFINE_ASM_ATTRIBUTES */
83
84 static void
85 process_rtx (desc)
86 rtx* desc;
87 {
88 if (GET_CODE (*desc) == DEFINE_INSN_AND_SPLIT)
89 {
90 struct queue_elem* elem = xmalloc (sizeof (struct queue_elem));
91 const char *split_cond;
92
93 /* Create a split with values from the insn_and_split. */
94 rtx split = rtx_alloc (DEFINE_SPLIT);
95 XVEC (split, 0) = copy_rtx (XVEC (*desc, 1));
96 remove_constraints (XVEC (split, 0));
97 split_cond = XSTR (split, 1) = XSTR (*desc, 4);
98
99 /* If the split condition starts with "&&", append it to the
100 insn condition to create the new split condition. */
101 if (split_cond[0] == '&' && split_cond[1] == '&')
102 {
103 const char *insn_cond = XSTR (*desc, 2);
104 char *combined =
105 xmalloc (strlen (insn_cond) + strlen (split_cond) + 1);
106 strcpy (combined, insn_cond);
107 strcat (combined, split_cond);
108 XSTR (split, 1) = combined;
109 }
110
111 XVEC (split, 2) = XVEC (*desc, 5);
112 XSTR (split, 3) = XSTR (*desc, 6);
113
114 /* Fix up the DEFINE_INSN. */
115 PUT_CODE (*desc, DEFINE_INSN);
116 XVEC (*desc, 4) = XSTR (*desc, 7);
117
118 /* Return the DEFINE_INSN part, and put the DEFINE_SPLIT
119 in the queue. */
120 elem->next = rtx_ready_queue;
121 elem->data = split;
122 rtx_ready_queue = elem;
123 }
124 }
125
126 /* The entry point for initializing the reader. */
127
128 int
129 init_md_reader (filename)
130 const char *filename;
131 {
132
133 input_file = fopen (filename, "r");
134
135 if (input_file == 0)
136 {
137 perror (filename);
138 return FATAL_EXIT_CODE;
139 }
140
141 read_rtx_filename = filename;
142 sequence_num = 0;
143 rtx_ready_queue = NULL;
144
145 return SUCCESS_EXIT_CODE;
146 }
147
148
149 /* The entry point for reading a single rtx from an md file. */
150
151 rtx
152 read_md_rtx (lineno, seqnr)
153 int *lineno;
154 int *seqnr;
155 {
156 rtx desc;
157
158 if (rtx_ready_queue != NULL)
159 {
160 desc = rtx_ready_queue->data;
161 rtx_ready_queue = rtx_ready_queue->next;
162 }
163 else
164 {
165 int c;
166 c = read_skip_spaces (input_file);
167 if (c == EOF)
168 return NULL;
169
170 ungetc (c, input_file);
171 desc = read_rtx (input_file);
172 process_rtx (&desc);
173 }
174 *lineno = read_rtx_lineno;
175 *seqnr = sequence_num;
176 switch (GET_CODE (desc))
177 {
178 case DEFINE_INSN:
179 case DEFINE_EXPAND:
180 case DEFINE_SPLIT:
181 case DEFINE_PEEPHOLE:
182 case DEFINE_PEEPHOLE2:
183 sequence_num++;
184 break;
185
186 default:
187 break;
188 }
189
190 return desc;
191 }
This page took 0.05022 seconds and 6 git commands to generate.