Mercurial > hg > CbC > CbC_gcc
annotate gcc/read-rtl.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* RTL reader for GCC. |
2 Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
3 2003, 2004, 2005, 2007, 2008, 2010 |
0 | 4 Free Software Foundation, Inc. |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it under | |
9 the terms of the GNU General Public License as published by the Free | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "bconfig.h" | |
23 | |
24 /* Disable rtl checking; it conflicts with the iterator handling. */ | |
25 #undef ENABLE_RTL_CHECKING | |
26 | |
27 #include "system.h" | |
28 #include "coretypes.h" | |
29 #include "tm.h" | |
30 #include "rtl.h" | |
31 #include "obstack.h" | |
32 #include "hashtab.h" | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
33 #include "read-md.h" |
0 | 34 #include "gensupport.h" |
35 | |
36 /* One element in a singly-linked list of (integer, string) pairs. */ | |
37 struct map_value { | |
38 struct map_value *next; | |
39 int number; | |
40 const char *string; | |
41 }; | |
42 | |
43 /* Maps an iterator or attribute name to a list of (integer, string) pairs. | |
44 The integers are mode or code values; the strings are either C conditions | |
45 or attribute values. */ | |
46 struct mapping { | |
47 /* The name of the iterator or attribute. */ | |
48 const char *name; | |
49 | |
50 /* The group (modes or codes) to which the iterator or attribute belongs. */ | |
51 struct iterator_group *group; | |
52 | |
53 /* Gives a unique number to the attribute or iterator. Numbers are | |
54 allocated consecutively, starting at 0. */ | |
55 int index; | |
56 | |
57 /* The list of (integer, string) pairs. */ | |
58 struct map_value *values; | |
59 }; | |
60 | |
61 /* A structure for abstracting the common parts of code and mode iterators. */ | |
62 struct iterator_group { | |
63 /* Tables of "mapping" structures, one for attributes and one for iterators. */ | |
64 htab_t attrs, iterators; | |
65 | |
66 /* The number of "real" modes or codes (and by extension, the first | |
67 number available for use as an iterator placeholder). */ | |
68 int num_builtins; | |
69 | |
70 /* Treat the given string as the name of a standard mode or code and | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
71 return its integer value. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
72 int (*find_builtin) (const char *); |
0 | 73 |
74 /* Return true if the given rtx uses the given mode or code. */ | |
75 bool (*uses_iterator_p) (rtx, int); | |
76 | |
77 /* Make the given rtx use the given mode or code. */ | |
78 void (*apply_iterator) (rtx, int); | |
79 }; | |
80 | |
81 /* A structure used to pass data from read_rtx to apply_iterator_traverse | |
82 via htab_traverse. */ | |
83 struct iterator_traverse_data { | |
84 /* Instruction queue. */ | |
85 rtx queue; | |
86 /* Attributes seen for modes. */ | |
87 struct map_value *mode_maps; | |
88 /* The last unknown attribute used as a mode. */ | |
89 const char *unknown_mode_attr; | |
90 }; | |
91 | |
92 /* If CODE is the number of a code iterator, return a real rtx code that | |
93 has the same format. Return CODE otherwise. */ | |
94 #define BELLWETHER_CODE(CODE) \ | |
95 ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE]) | |
96 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
97 static int find_mode (const char *); |
0 | 98 static bool uses_mode_iterator_p (rtx, int); |
99 static void apply_mode_iterator (rtx, int); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
100 static int find_code (const char *); |
0 | 101 static bool uses_code_iterator_p (rtx, int); |
102 static void apply_code_iterator (rtx, int); | |
103 static const char *apply_iterator_to_string (const char *, struct mapping *, int); | |
104 static rtx apply_iterator_to_rtx (rtx, struct mapping *, int, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
105 struct map_value *, const char **); |
0 | 106 static bool uses_iterator_p (rtx, struct mapping *); |
107 static const char *add_condition_to_string (const char *, const char *); | |
108 static void add_condition_to_rtx (rtx, const char *); | |
109 static int apply_iterator_traverse (void **, void *); | |
110 static struct mapping *add_mapping (struct iterator_group *, htab_t t, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
111 const char *); |
0 | 112 static struct map_value **add_map_value (struct map_value **, |
113 int, const char *); | |
114 static void initialize_iterators (void); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
115 static void read_conditions (void); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
116 static void validate_const_int (const char *); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
117 static int find_iterator (struct iterator_group *, const char *); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
118 static struct mapping *read_mapping (struct iterator_group *, htab_t); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
119 static void check_code_iterator (struct mapping *); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
120 static rtx read_rtx_code (const char *, struct map_value **); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
121 static rtx read_nested_rtx (struct map_value **); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
122 static rtx read_rtx_variadic (struct map_value **, rtx); |
0 | 123 |
124 /* The mode and code iterator structures. */ | |
125 static struct iterator_group modes, codes; | |
126 | |
127 /* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE). */ | |
128 static enum rtx_code *bellwether_codes; | |
129 | |
130 /* Implementations of the iterator_group callbacks for modes. */ | |
131 | |
132 static int | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
133 find_mode (const char *name) |
0 | 134 { |
135 int i; | |
136 | |
137 for (i = 0; i < NUM_MACHINE_MODES; i++) | |
138 if (strcmp (GET_MODE_NAME (i), name) == 0) | |
139 return i; | |
140 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
141 fatal_with_file_and_line ("unknown mode `%s'", name); |
0 | 142 } |
143 | |
144 static bool | |
145 uses_mode_iterator_p (rtx x, int mode) | |
146 { | |
147 return (int) GET_MODE (x) == mode; | |
148 } | |
149 | |
150 static void | |
151 apply_mode_iterator (rtx x, int mode) | |
152 { | |
153 PUT_MODE (x, (enum machine_mode) mode); | |
154 } | |
155 | |
156 /* Implementations of the iterator_group callbacks for codes. */ | |
157 | |
158 static int | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
159 find_code (const char *name) |
0 | 160 { |
161 int i; | |
162 | |
163 for (i = 0; i < NUM_RTX_CODE; i++) | |
164 if (strcmp (GET_RTX_NAME (i), name) == 0) | |
165 return i; | |
166 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
167 fatal_with_file_and_line ("unknown rtx code `%s'", name); |
0 | 168 } |
169 | |
170 static bool | |
171 uses_code_iterator_p (rtx x, int code) | |
172 { | |
173 return (int) GET_CODE (x) == code; | |
174 } | |
175 | |
176 static void | |
177 apply_code_iterator (rtx x, int code) | |
178 { | |
179 PUT_CODE (x, (enum rtx_code) code); | |
180 } | |
181 | |
182 /* Map a code or mode attribute string P to the underlying string for | |
183 ITERATOR and VALUE. */ | |
184 | |
185 static struct map_value * | |
186 map_attr_string (const char *p, struct mapping *iterator, int value) | |
187 { | |
188 const char *attr; | |
189 struct mapping *m; | |
190 struct map_value *v; | |
191 | |
192 /* If there's a "iterator:" prefix, check whether the iterator name matches. | |
193 Set ATTR to the start of the attribute name. */ | |
194 attr = strchr (p, ':'); | |
195 if (attr == 0) | |
196 attr = p; | |
197 else | |
198 { | |
199 if (strncmp (p, iterator->name, attr - p) != 0 | |
200 || iterator->name[attr - p] != 0) | |
201 return 0; | |
202 attr++; | |
203 } | |
204 | |
205 /* Find the attribute specification. */ | |
206 m = (struct mapping *) htab_find (iterator->group->attrs, &attr); | |
207 if (m == 0) | |
208 return 0; | |
209 | |
210 /* Find the attribute value for VALUE. */ | |
211 for (v = m->values; v != 0; v = v->next) | |
212 if (v->number == value) | |
213 break; | |
214 | |
215 return v; | |
216 } | |
217 | |
218 /* Given an attribute string used as a machine mode, return an index | |
219 to store in the machine mode to be translated by | |
220 apply_iterator_to_rtx. */ | |
221 | |
222 static unsigned int | |
223 mode_attr_index (struct map_value **mode_maps, const char *string) | |
224 { | |
225 char *p; | |
226 struct map_value *mv; | |
227 | |
228 /* Copy the attribute string into permanent storage, without the | |
229 angle brackets around it. */ | |
230 obstack_grow0 (&string_obstack, string + 1, strlen (string) - 2); | |
231 p = XOBFINISH (&string_obstack, char *); | |
232 | |
233 mv = XNEW (struct map_value); | |
234 mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1; | |
235 mv->string = p; | |
236 mv->next = *mode_maps; | |
237 *mode_maps = mv; | |
238 | |
239 /* We return a code which we can map back into this string: the | |
240 number of machine modes + the number of mode iterators + the index | |
241 we just used. */ | |
242 return MAX_MACHINE_MODE + htab_elements (modes.iterators) + mv->number; | |
243 } | |
244 | |
245 /* Apply MODE_MAPS to the top level of X, expanding cases where an | |
246 attribute is used for a mode. ITERATOR is the current iterator we are | |
247 expanding, and VALUE is the value to which we are expanding it. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
248 This sets *UNKNOWN to true if we find a mode attribute which has not |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
249 yet been defined, and does not change it otherwise. */ |
0 | 250 |
251 static void | |
252 apply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *iterator, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
253 int value, const char **unknown) |
0 | 254 { |
255 unsigned int offset; | |
256 int indx; | |
257 struct map_value *pm; | |
258 | |
259 offset = MAX_MACHINE_MODE + htab_elements (modes.iterators); | |
260 if (GET_MODE (x) < offset) | |
261 return; | |
262 | |
263 indx = GET_MODE (x) - offset; | |
264 for (pm = mode_maps; pm; pm = pm->next) | |
265 { | |
266 if (pm->number == indx) | |
267 { | |
268 struct map_value *v; | |
269 | |
270 v = map_attr_string (pm->string, iterator, value); | |
271 if (v) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
272 PUT_MODE (x, (enum machine_mode) find_mode (v->string)); |
0 | 273 else |
274 *unknown = pm->string; | |
275 return; | |
276 } | |
277 } | |
278 } | |
279 | |
280 /* Given that ITERATOR is being expanded as VALUE, apply the appropriate | |
281 string substitutions to STRING. Return the new string if any changes | |
282 were needed, otherwise return STRING itself. */ | |
283 | |
284 static const char * | |
285 apply_iterator_to_string (const char *string, struct mapping *iterator, int value) | |
286 { | |
287 char *base, *copy, *p, *start, *end; | |
288 struct map_value *v; | |
289 | |
290 if (string == 0) | |
291 return string; | |
292 | |
293 base = p = copy = ASTRDUP (string); | |
294 while ((start = strchr (p, '<')) && (end = strchr (start, '>'))) | |
295 { | |
296 p = start + 1; | |
297 | |
298 *end = 0; | |
299 v = map_attr_string (p, iterator, value); | |
300 *end = '>'; | |
301 if (v == 0) | |
302 continue; | |
303 | |
304 /* Add everything between the last copied byte and the '<', | |
305 then add in the attribute value. */ | |
306 obstack_grow (&string_obstack, base, start - base); | |
307 obstack_grow (&string_obstack, v->string, strlen (v->string)); | |
308 base = end + 1; | |
309 } | |
310 if (base != copy) | |
311 { | |
312 obstack_grow (&string_obstack, base, strlen (base) + 1); | |
313 copy = XOBFINISH (&string_obstack, char *); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
314 copy_md_ptr_loc (copy, string); |
0 | 315 return copy; |
316 } | |
317 return string; | |
318 } | |
319 | |
320 /* Return a copy of ORIGINAL in which all uses of ITERATOR have been | |
321 replaced by VALUE. MODE_MAPS holds information about attribute | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
322 strings used for modes. This sets *UNKNOWN_MODE_ATTR to the value of |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
323 an unknown mode attribute, and does not change it otherwise. */ |
0 | 324 |
325 static rtx | |
326 apply_iterator_to_rtx (rtx original, struct mapping *iterator, int value, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
327 struct map_value *mode_maps, |
0 | 328 const char **unknown_mode_attr) |
329 { | |
330 struct iterator_group *group; | |
331 const char *format_ptr; | |
332 int i, j; | |
333 rtx x; | |
334 enum rtx_code bellwether_code; | |
335 | |
336 if (original == 0) | |
337 return original; | |
338 | |
339 /* Create a shallow copy of ORIGINAL. */ | |
340 bellwether_code = BELLWETHER_CODE (GET_CODE (original)); | |
341 x = rtx_alloc (bellwether_code); | |
342 memcpy (x, original, RTX_CODE_SIZE (bellwether_code)); | |
343 | |
344 /* Change the mode or code itself. */ | |
345 group = iterator->group; | |
346 if (group->uses_iterator_p (x, iterator->index + group->num_builtins)) | |
347 group->apply_iterator (x, value); | |
348 | |
349 if (mode_maps) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
350 apply_mode_maps (x, mode_maps, iterator, value, unknown_mode_attr); |
0 | 351 |
352 /* Change each string and recursively change each rtx. */ | |
353 format_ptr = GET_RTX_FORMAT (bellwether_code); | |
354 for (i = 0; format_ptr[i] != 0; i++) | |
355 switch (format_ptr[i]) | |
356 { | |
357 case 'T': | |
358 XTMPL (x, i) = apply_iterator_to_string (XTMPL (x, i), iterator, value); | |
359 break; | |
360 | |
361 case 'S': | |
362 case 's': | |
363 XSTR (x, i) = apply_iterator_to_string (XSTR (x, i), iterator, value); | |
364 break; | |
365 | |
366 case 'e': | |
367 XEXP (x, i) = apply_iterator_to_rtx (XEXP (x, i), iterator, value, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
368 mode_maps, unknown_mode_attr); |
0 | 369 break; |
370 | |
371 case 'V': | |
372 case 'E': | |
373 if (XVEC (original, i)) | |
374 { | |
375 XVEC (x, i) = rtvec_alloc (XVECLEN (original, i)); | |
376 for (j = 0; j < XVECLEN (x, i); j++) | |
377 XVECEXP (x, i, j) = apply_iterator_to_rtx (XVECEXP (original, i, j), | |
378 iterator, value, mode_maps, | |
379 unknown_mode_attr); | |
380 } | |
381 break; | |
382 | |
383 default: | |
384 break; | |
385 } | |
386 return x; | |
387 } | |
388 | |
389 /* Return true if X (or some subexpression of X) uses iterator ITERATOR. */ | |
390 | |
391 static bool | |
392 uses_iterator_p (rtx x, struct mapping *iterator) | |
393 { | |
394 struct iterator_group *group; | |
395 const char *format_ptr; | |
396 int i, j; | |
397 | |
398 if (x == 0) | |
399 return false; | |
400 | |
401 group = iterator->group; | |
402 if (group->uses_iterator_p (x, iterator->index + group->num_builtins)) | |
403 return true; | |
404 | |
405 format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x))); | |
406 for (i = 0; format_ptr[i] != 0; i++) | |
407 switch (format_ptr[i]) | |
408 { | |
409 case 'e': | |
410 if (uses_iterator_p (XEXP (x, i), iterator)) | |
411 return true; | |
412 break; | |
413 | |
414 case 'V': | |
415 case 'E': | |
416 if (XVEC (x, i)) | |
417 for (j = 0; j < XVECLEN (x, i); j++) | |
418 if (uses_iterator_p (XVECEXP (x, i, j), iterator)) | |
419 return true; | |
420 break; | |
421 | |
422 default: | |
423 break; | |
424 } | |
425 return false; | |
426 } | |
427 | |
428 /* Return a condition that must satisfy both ORIGINAL and EXTRA. If ORIGINAL | |
429 has the form "&& ..." (as used in define_insn_and_splits), assume that | |
430 EXTRA is already satisfied. Empty strings are treated like "true". */ | |
431 | |
432 static const char * | |
433 add_condition_to_string (const char *original, const char *extra) | |
434 { | |
435 if (original != 0 && original[0] == '&' && original[1] == '&') | |
436 return original; | |
437 return join_c_conditions (original, extra); | |
438 } | |
439 | |
440 /* Like add_condition, but applied to all conditions in rtx X. */ | |
441 | |
442 static void | |
443 add_condition_to_rtx (rtx x, const char *extra) | |
444 { | |
445 switch (GET_CODE (x)) | |
446 { | |
447 case DEFINE_INSN: | |
448 case DEFINE_EXPAND: | |
449 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); | |
450 break; | |
451 | |
452 case DEFINE_SPLIT: | |
453 case DEFINE_PEEPHOLE: | |
454 case DEFINE_PEEPHOLE2: | |
455 case DEFINE_COND_EXEC: | |
456 XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra); | |
457 break; | |
458 | |
459 case DEFINE_INSN_AND_SPLIT: | |
460 XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra); | |
461 XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra); | |
462 break; | |
463 | |
464 default: | |
465 break; | |
466 } | |
467 } | |
468 | |
469 /* A htab_traverse callback. Search the EXPR_LIST given by DATA | |
470 for rtxes that use the iterator in *SLOT. Replace each such rtx | |
471 with a list of expansions. */ | |
472 | |
473 static int | |
474 apply_iterator_traverse (void **slot, void *data) | |
475 { | |
476 struct iterator_traverse_data *mtd = (struct iterator_traverse_data *) data; | |
477 struct mapping *iterator; | |
478 struct map_value *v; | |
479 rtx elem, new_elem, original, x; | |
480 | |
481 iterator = (struct mapping *) *slot; | |
482 for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1)) | |
483 if (uses_iterator_p (XEXP (elem, 0), iterator)) | |
484 { | |
485 /* For each iterator we expand, we set UNKNOWN_MODE_ATTR to NULL. | |
486 If apply_iterator_rtx finds an unknown attribute for a mode, | |
487 it will set it to the attribute. We want to know whether | |
488 the attribute is unknown after we have expanded all | |
489 possible iterators, so setting it to NULL here gives us the | |
490 right result when the hash table traversal is complete. */ | |
491 mtd->unknown_mode_attr = NULL; | |
492 | |
493 original = XEXP (elem, 0); | |
494 for (v = iterator->values; v != 0; v = v->next) | |
495 { | |
496 x = apply_iterator_to_rtx (original, iterator, v->number, | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
497 mtd->mode_maps, |
0 | 498 &mtd->unknown_mode_attr); |
499 add_condition_to_rtx (x, v->string); | |
500 if (v != iterator->values) | |
501 { | |
502 /* Insert a new EXPR_LIST node after ELEM and put the | |
503 new expansion there. */ | |
504 new_elem = rtx_alloc (EXPR_LIST); | |
505 XEXP (new_elem, 1) = XEXP (elem, 1); | |
506 XEXP (elem, 1) = new_elem; | |
507 elem = new_elem; | |
508 } | |
509 XEXP (elem, 0) = x; | |
510 } | |
511 } | |
512 return 1; | |
513 } | |
514 | |
515 /* Add a new "mapping" structure to hashtable TABLE. NAME is the name | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
516 of the mapping and GROUP is the group to which it belongs. */ |
0 | 517 |
518 static struct mapping * | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
519 add_mapping (struct iterator_group *group, htab_t table, const char *name) |
0 | 520 { |
521 struct mapping *m; | |
522 void **slot; | |
523 | |
524 m = XNEW (struct mapping); | |
525 m->name = xstrdup (name); | |
526 m->group = group; | |
527 m->index = htab_elements (table); | |
528 m->values = 0; | |
529 | |
530 slot = htab_find_slot (table, m, INSERT); | |
531 if (*slot != 0) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
532 fatal_with_file_and_line ("`%s' already defined", name); |
0 | 533 |
534 *slot = m; | |
535 return m; | |
536 } | |
537 | |
538 /* Add the pair (NUMBER, STRING) to a list of map_value structures. | |
539 END_PTR points to the current null terminator for the list; return | |
540 a pointer the new null terminator. */ | |
541 | |
542 static struct map_value ** | |
543 add_map_value (struct map_value **end_ptr, int number, const char *string) | |
544 { | |
545 struct map_value *value; | |
546 | |
547 value = XNEW (struct map_value); | |
548 value->next = 0; | |
549 value->number = number; | |
550 value->string = string; | |
551 | |
552 *end_ptr = value; | |
553 return &value->next; | |
554 } | |
555 | |
556 /* Do one-time initialization of the mode and code attributes. */ | |
557 | |
558 static void | |
559 initialize_iterators (void) | |
560 { | |
561 struct mapping *lower, *upper; | |
562 struct map_value **lower_ptr, **upper_ptr; | |
563 char *copy, *p; | |
564 int i; | |
565 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
566 modes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
567 modes.iterators = htab_create (13, leading_string_hash, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
568 leading_string_eq_p, 0); |
0 | 569 modes.num_builtins = MAX_MACHINE_MODE; |
570 modes.find_builtin = find_mode; | |
571 modes.uses_iterator_p = uses_mode_iterator_p; | |
572 modes.apply_iterator = apply_mode_iterator; | |
573 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
574 codes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
575 codes.iterators = htab_create (13, leading_string_hash, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
576 leading_string_eq_p, 0); |
0 | 577 codes.num_builtins = NUM_RTX_CODE; |
578 codes.find_builtin = find_code; | |
579 codes.uses_iterator_p = uses_code_iterator_p; | |
580 codes.apply_iterator = apply_code_iterator; | |
581 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
582 lower = add_mapping (&modes, modes.attrs, "mode"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
583 upper = add_mapping (&modes, modes.attrs, "MODE"); |
0 | 584 lower_ptr = &lower->values; |
585 upper_ptr = &upper->values; | |
586 for (i = 0; i < MAX_MACHINE_MODE; i++) | |
587 { | |
588 copy = xstrdup (GET_MODE_NAME (i)); | |
589 for (p = copy; *p != 0; p++) | |
590 *p = TOLOWER (*p); | |
591 | |
592 upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i)); | |
593 lower_ptr = add_map_value (lower_ptr, i, copy); | |
594 } | |
595 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
596 lower = add_mapping (&codes, codes.attrs, "code"); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
597 upper = add_mapping (&codes, codes.attrs, "CODE"); |
0 | 598 lower_ptr = &lower->values; |
599 upper_ptr = &upper->values; | |
600 for (i = 0; i < NUM_RTX_CODE; i++) | |
601 { | |
602 copy = xstrdup (GET_RTX_NAME (i)); | |
603 for (p = copy; *p != 0; p++) | |
604 *p = TOUPPER (*p); | |
605 | |
606 lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i)); | |
607 upper_ptr = add_map_value (upper_ptr, i, copy); | |
608 } | |
609 } | |
610 | |
611 /* Provide a version of a function to read a long long if the system does | |
612 not provide one. */ | |
613 #if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ) | |
614 HOST_WIDE_INT atoll (const char *); | |
615 | |
616 HOST_WIDE_INT | |
617 atoll (const char *p) | |
618 { | |
619 int neg = 0; | |
620 HOST_WIDE_INT tmp_wide; | |
621 | |
622 while (ISSPACE (*p)) | |
623 p++; | |
624 if (*p == '-') | |
625 neg = 1, p++; | |
626 else if (*p == '+') | |
627 p++; | |
628 | |
629 tmp_wide = 0; | |
630 while (ISDIGIT (*p)) | |
631 { | |
632 HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0'); | |
633 if (new_wide < tmp_wide) | |
634 { | |
635 /* Return INT_MAX equiv on overflow. */ | |
636 tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1; | |
637 break; | |
638 } | |
639 tmp_wide = new_wide; | |
640 p++; | |
641 } | |
642 | |
643 if (neg) | |
644 tmp_wide = -tmp_wide; | |
645 return tmp_wide; | |
646 } | |
647 #endif | |
648 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
649 /* Process a define_conditions directive, starting with the optional |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
650 space after the "define_conditions". The directive looks like this: |
0 | 651 |
652 (define_conditions [ | |
653 (number "string") | |
654 (number "string") | |
655 ... | |
656 ]) | |
657 | |
658 It's not intended to appear in machine descriptions. It is | |
659 generated by (the program generated by) genconditions.c, and | |
660 slipped in at the beginning of the sequence of MD files read by | |
661 most of the other generators. */ | |
662 static void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
663 read_conditions (void) |
0 | 664 { |
665 int c; | |
666 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
667 c = read_skip_spaces (); |
0 | 668 if (c != '[') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
669 fatal_expected_char ('[', c); |
0 | 670 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
671 while ( (c = read_skip_spaces ()) != ']') |
0 | 672 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
673 struct md_name name; |
0 | 674 char *expr; |
675 int value; | |
676 | |
677 if (c != '(') | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
678 fatal_expected_char ('(', c); |
0 | 679 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
680 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
681 validate_const_int (name.string); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
682 value = atoi (name.string); |
0 | 683 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
684 c = read_skip_spaces (); |
0 | 685 if (c != '"') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
686 fatal_expected_char ('"', c); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
687 expr = read_quoted_string (); |
0 | 688 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
689 c = read_skip_spaces (); |
0 | 690 if (c != ')') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
691 fatal_expected_char (')', c); |
0 | 692 |
693 add_c_test (expr, value); | |
694 } | |
695 } | |
696 | |
697 static void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
698 validate_const_int (const char *string) |
0 | 699 { |
700 const char *cp; | |
701 int valid = 1; | |
702 | |
703 cp = string; | |
704 while (*cp && ISSPACE (*cp)) | |
705 cp++; | |
706 if (*cp == '-' || *cp == '+') | |
707 cp++; | |
708 if (*cp == 0) | |
709 valid = 0; | |
710 for (; *cp; cp++) | |
711 if (! ISDIGIT (*cp)) | |
712 valid = 0; | |
713 if (!valid) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
714 fatal_with_file_and_line ("invalid decimal constant \"%s\"\n", string); |
0 | 715 } |
716 | |
717 /* Search GROUP for a mode or code called NAME and return its numerical | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
718 identifier. */ |
0 | 719 |
720 static int | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
721 find_iterator (struct iterator_group *group, const char *name) |
0 | 722 { |
723 struct mapping *m; | |
724 | |
725 m = (struct mapping *) htab_find (group->iterators, &name); | |
726 if (m != 0) | |
727 return m->index + group->num_builtins; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
728 return group->find_builtin (name); |
0 | 729 } |
730 | |
731 /* Finish reading a declaration of the form: | |
732 | |
733 (define... <name> [<value1> ... <valuen>]) | |
734 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
735 from the MD file, where each <valuei> is either a bare symbol name or a |
0 | 736 "(<name> <string>)" pair. The "(define..." part has already been read. |
737 | |
738 Represent the declaration as a "mapping" structure; add it to TABLE | |
739 (which belongs to GROUP) and return it. */ | |
740 | |
741 static struct mapping * | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
742 read_mapping (struct iterator_group *group, htab_t table) |
0 | 743 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
744 struct md_name name; |
0 | 745 struct mapping *m; |
746 struct map_value **end_ptr; | |
747 const char *string; | |
748 int number, c; | |
749 | |
750 /* Read the mapping name and create a structure for it. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
751 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
752 m = add_mapping (group, table, name.string); |
0 | 753 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
754 c = read_skip_spaces (); |
0 | 755 if (c != '[') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
756 fatal_expected_char ('[', c); |
0 | 757 |
758 /* Read each value. */ | |
759 end_ptr = &m->values; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
760 c = read_skip_spaces (); |
0 | 761 do |
762 { | |
763 if (c != '(') | |
764 { | |
765 /* A bare symbol name that is implicitly paired to an | |
766 empty string. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
767 unread_char (c); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
768 read_name (&name); |
0 | 769 string = ""; |
770 } | |
771 else | |
772 { | |
773 /* A "(name string)" pair. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
774 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
775 string = read_string (false); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
776 c = read_skip_spaces (); |
0 | 777 if (c != ')') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
778 fatal_expected_char (')', c); |
0 | 779 } |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
780 number = group->find_builtin (name.string); |
0 | 781 end_ptr = add_map_value (end_ptr, number, string); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
782 c = read_skip_spaces (); |
0 | 783 } |
784 while (c != ']'); | |
785 | |
786 return m; | |
787 } | |
788 | |
789 /* Check newly-created code iterator ITERATOR to see whether every code has the | |
790 same format. Initialize the iterator's entry in bellwether_codes. */ | |
791 | |
792 static void | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
793 check_code_iterator (struct mapping *iterator) |
0 | 794 { |
795 struct map_value *v; | |
796 enum rtx_code bellwether; | |
797 | |
798 bellwether = (enum rtx_code) iterator->values->number; | |
799 for (v = iterator->values->next; v != 0; v = v->next) | |
800 if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
801 fatal_with_file_and_line ("code iterator `%s' combines " |
0 | 802 "different rtx formats", iterator->name); |
803 | |
804 bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes, | |
805 iterator->index + 1); | |
806 bellwether_codes[iterator->index] = bellwether; | |
807 } | |
808 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
809 /* Read an rtx-related declaration from the MD file, given that it |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
810 starts with directive name RTX_NAME. Return true if it expands to |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
811 one or more rtxes (as defined by rtx.def). When returning true, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
812 store the list of rtxes as an EXPR_LIST in *X. */ |
0 | 813 |
814 bool | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
815 read_rtx (const char *rtx_name, rtx *x) |
0 | 816 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
817 static rtx queue_head; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
818 struct map_value *mode_maps; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
819 struct iterator_traverse_data mtd; |
0 | 820 |
821 /* Do one-time initialization. */ | |
822 if (queue_head == 0) | |
823 { | |
824 initialize_iterators (); | |
825 queue_head = rtx_alloc (EXPR_LIST); | |
826 } | |
827 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
828 /* Handle various rtx-related declarations that aren't themselves |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
829 encoded as rtxes. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
830 if (strcmp (rtx_name, "define_conditions") == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
831 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
832 read_conditions (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
833 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
834 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
835 if (strcmp (rtx_name, "define_mode_attr") == 0) |
0 | 836 { |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
837 read_mapping (&modes, modes.attrs); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
838 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
839 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
840 if (strcmp (rtx_name, "define_mode_iterator") == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
841 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
842 read_mapping (&modes, modes.iterators); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
843 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
844 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
845 if (strcmp (rtx_name, "define_code_attr") == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
846 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
847 read_mapping (&codes, codes.attrs); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
848 return false; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
849 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
850 if (strcmp (rtx_name, "define_code_iterator") == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
851 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
852 check_code_iterator (read_mapping (&codes, codes.iterators)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
853 return false; |
0 | 854 } |
855 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
856 mode_maps = 0; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
857 XEXP (queue_head, 0) = read_rtx_code (rtx_name, &mode_maps); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
858 XEXP (queue_head, 1) = 0; |
0 | 859 |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
860 mtd.queue = queue_head; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
861 mtd.mode_maps = mode_maps; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
862 mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
863 htab_traverse (modes.iterators, apply_iterator_traverse, &mtd); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
864 htab_traverse (codes.iterators, apply_iterator_traverse, &mtd); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
865 if (mtd.unknown_mode_attr) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
866 fatal_with_file_and_line ("undefined attribute '%s' used for mode", |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
867 mtd.unknown_mode_attr); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
868 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
869 *x = queue_head; |
0 | 870 return true; |
871 } | |
872 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
873 /* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
874 either an rtx code or a code iterator. Parse the rest of the rtx and |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
875 return it. MODE_MAPS is as for iterator_traverse_data. */ |
0 | 876 |
877 static rtx | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
878 read_rtx_code (const char *code_name, struct map_value **mode_maps) |
0 | 879 { |
880 int i; | |
881 RTX_CODE real_code, bellwether_code; | |
882 const char *format_ptr; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
883 struct md_name name; |
0 | 884 rtx return_rtx; |
885 int c; | |
886 int tmp_int; | |
887 HOST_WIDE_INT tmp_wide; | |
888 | |
889 /* Linked list structure for making RTXs: */ | |
890 struct rtx_list | |
891 { | |
892 struct rtx_list *next; | |
893 rtx value; /* Value of this node. */ | |
894 }; | |
895 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
896 real_code = (enum rtx_code) find_iterator (&codes, code_name); |
0 | 897 bellwether_code = BELLWETHER_CODE (real_code); |
898 | |
899 /* If we end up with an insn expression then we free this space below. */ | |
900 return_rtx = rtx_alloc (bellwether_code); | |
901 format_ptr = GET_RTX_FORMAT (bellwether_code); | |
902 PUT_CODE (return_rtx, real_code); | |
903 | |
904 /* If what follows is `: mode ', read it and | |
905 store the mode in the rtx. */ | |
906 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
907 i = read_skip_spaces (); |
0 | 908 if (i == ':') |
909 { | |
910 unsigned int mode; | |
911 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
912 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
913 if (name.string[0] != '<' || name.string[strlen (name.string) - 1] != '>') |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
914 mode = find_iterator (&modes, name.string); |
0 | 915 else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
916 mode = mode_attr_index (mode_maps, name.string); |
0 | 917 PUT_MODE (return_rtx, (enum machine_mode) mode); |
918 if (GET_MODE (return_rtx) != mode) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
919 fatal_with_file_and_line ("mode too large"); |
0 | 920 } |
921 else | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
922 unread_char (i); |
0 | 923 |
924 for (i = 0; format_ptr[i] != 0; i++) | |
925 switch (format_ptr[i]) | |
926 { | |
927 /* 0 means a field for internal use only. | |
928 Don't expect it to be present in the input. */ | |
929 case '0': | |
930 break; | |
931 | |
932 case 'e': | |
933 case 'u': | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
934 XEXP (return_rtx, i) = read_nested_rtx (mode_maps); |
0 | 935 break; |
936 | |
937 case 'V': | |
938 /* 'V' is an optional vector: if a closeparen follows, | |
939 just store NULL for this element. */ | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
940 c = read_skip_spaces (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
941 unread_char (c); |
0 | 942 if (c == ')') |
943 { | |
944 XVEC (return_rtx, i) = 0; | |
945 break; | |
946 } | |
947 /* Now process the vector. */ | |
948 | |
949 case 'E': | |
950 { | |
951 /* Obstack to store scratch vector in. */ | |
952 struct obstack vector_stack; | |
953 int list_counter = 0; | |
954 rtvec return_vec = NULL_RTVEC; | |
955 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
956 c = read_skip_spaces (); |
0 | 957 if (c != '[') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
958 fatal_expected_char ('[', c); |
0 | 959 |
960 /* Add expressions to a list, while keeping a count. */ | |
961 obstack_init (&vector_stack); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
962 while ((c = read_skip_spaces ()) && c != ']') |
0 | 963 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
964 if (c == EOF) |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
965 fatal_expected_char (']', c); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
966 unread_char (c); |
0 | 967 list_counter++; |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
968 obstack_ptr_grow (&vector_stack, read_nested_rtx (mode_maps)); |
0 | 969 } |
970 if (list_counter > 0) | |
971 { | |
972 return_vec = rtvec_alloc (list_counter); | |
973 memcpy (&return_vec->elem[0], obstack_finish (&vector_stack), | |
974 list_counter * sizeof (rtx)); | |
975 } | |
976 else if (format_ptr[i] == 'E') | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
977 fatal_with_file_and_line ("vector must have at least one element"); |
0 | 978 XVEC (return_rtx, i) = return_vec; |
979 obstack_free (&vector_stack, NULL); | |
980 /* close bracket gotten */ | |
981 } | |
982 break; | |
983 | |
984 case 'S': | |
985 case 'T': | |
986 case 's': | |
987 { | |
988 char *stringbuf; | |
989 int star_if_braced; | |
990 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
991 c = read_skip_spaces (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
992 unread_char (c); |
0 | 993 if (c == ')') |
994 { | |
995 /* 'S' fields are optional and should be NULL if no string | |
996 was given. Also allow normal 's' and 'T' strings to be | |
997 omitted, treating them in the same way as empty strings. */ | |
998 XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : ""); | |
999 break; | |
1000 } | |
1001 | |
1002 /* The output template slot of a DEFINE_INSN, | |
1003 DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically | |
1004 gets a star inserted as its first character, if it is | |
1005 written with a brace block instead of a string constant. */ | |
1006 star_if_braced = (format_ptr[i] == 'T'); | |
1007 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1008 stringbuf = read_string (star_if_braced); |
0 | 1009 |
1010 /* For insn patterns, we want to provide a default name | |
1011 based on the file and line, like "*foo.md:12", if the | |
1012 given name is blank. These are only for define_insn and | |
1013 define_insn_and_split, to aid debugging. */ | |
1014 if (*stringbuf == '\0' | |
1015 && i == 0 | |
1016 && (GET_CODE (return_rtx) == DEFINE_INSN | |
1017 || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT)) | |
1018 { | |
1019 char line_name[20]; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1020 const char *fn = (read_md_filename ? read_md_filename : "rtx"); |
0 | 1021 const char *slash; |
1022 for (slash = fn; *slash; slash ++) | |
1023 if (*slash == '/' || *slash == '\\' || *slash == ':') | |
1024 fn = slash + 1; | |
1025 obstack_1grow (&string_obstack, '*'); | |
1026 obstack_grow (&string_obstack, fn, strlen (fn)); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1027 sprintf (line_name, ":%d", read_md_lineno); |
0 | 1028 obstack_grow (&string_obstack, line_name, strlen (line_name)+1); |
1029 stringbuf = XOBFINISH (&string_obstack, char *); | |
1030 } | |
1031 | |
1032 if (star_if_braced) | |
1033 XTMPL (return_rtx, i) = stringbuf; | |
1034 else | |
1035 XSTR (return_rtx, i) = stringbuf; | |
1036 } | |
1037 break; | |
1038 | |
1039 case 'w': | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1040 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1041 validate_const_int (name.string); |
0 | 1042 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1043 tmp_wide = atoi (name.string); |
0 | 1044 #else |
1045 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1046 tmp_wide = atol (name.string); |
0 | 1047 #else |
1048 /* Prefer atoll over atoq, since the former is in the ISO C99 standard. | |
1049 But prefer not to use our hand-rolled function above either. */ | |
1050 #if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ) | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1051 tmp_wide = atoll (name.string); |
0 | 1052 #else |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1053 tmp_wide = atoq (name.string); |
0 | 1054 #endif |
1055 #endif | |
1056 #endif | |
1057 XWINT (return_rtx, i) = tmp_wide; | |
1058 break; | |
1059 | |
1060 case 'i': | |
1061 case 'n': | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1062 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1063 validate_const_int (name.string); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1064 tmp_int = atoi (name.string); |
0 | 1065 XINT (return_rtx, i) = tmp_int; |
1066 break; | |
1067 | |
1068 default: | |
1069 gcc_unreachable (); | |
1070 } | |
1071 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1072 c = read_skip_spaces (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1073 /* Syntactic sugar for AND and IOR, allowing Lisp-like |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1074 arbitrary number of arguments for them. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1075 if (c == '(' |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1076 && (GET_CODE (return_rtx) == AND |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1077 || GET_CODE (return_rtx) == IOR)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1078 return read_rtx_variadic (mode_maps, return_rtx); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1079 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1080 unread_char (c); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1081 return return_rtx; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1082 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1083 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1084 /* Read a nested rtx construct from the MD file and return it. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1085 MODE_MAPS is as for iterator_traverse_data. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1086 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1087 static rtx |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1088 read_nested_rtx (struct map_value **mode_maps) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1089 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1090 struct md_name name; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1091 int c; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1092 rtx return_rtx; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1093 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1094 c = read_skip_spaces (); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1095 if (c != '(') |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1096 fatal_expected_char ('(', c); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1097 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1098 read_name (&name); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1099 if (strcmp (name.string, "nil") == 0) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1100 return_rtx = NULL; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1101 else |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1102 return_rtx = read_rtx_code (name.string, mode_maps); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1103 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1104 c = read_skip_spaces (); |
0 | 1105 if (c != ')') |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1106 fatal_expected_char (')', c); |
0 | 1107 |
1108 return return_rtx; | |
1109 } | |
1110 | |
1111 /* Mutually recursive subroutine of read_rtx which reads | |
1112 (thing x1 x2 x3 ...) and produces RTL as if | |
1113 (thing x1 (thing x2 (thing x3 ...))) had been written. | |
1114 When called, FORM is (thing x1 x2), and the file position | |
1115 is just past the leading parenthesis of x3. Only works | |
1116 for THINGs which are dyadic expressions, e.g. AND, IOR. */ | |
1117 static rtx | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1118 read_rtx_variadic (struct map_value **mode_maps, rtx form) |
0 | 1119 { |
1120 char c = '('; | |
1121 rtx p = form, q; | |
1122 | |
1123 do | |
1124 { | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1125 unread_char (c); |
0 | 1126 |
1127 q = rtx_alloc (GET_CODE (p)); | |
1128 PUT_MODE (q, GET_MODE (p)); | |
1129 | |
1130 XEXP (q, 0) = XEXP (p, 1); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1131 XEXP (q, 1) = read_nested_rtx (mode_maps); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1132 |
0 | 1133 XEXP (p, 1) = q; |
1134 p = q; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1135 c = read_skip_spaces (); |
0 | 1136 } |
1137 while (c == '('); | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1138 unread_char (c); |
0 | 1139 return form; |
1140 } |