|
|
1.1 root 1: /* Generate code from machine description to compute values of attributes.
2: Copyright (C) 1991 Free Software Foundation, Inc.
3: Contributed by Richard Kenner ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: /* This program handles insn attribues and the DEFINE_DELAY and
22: DEFINE_FUNCTION_UNIT definitions.
23:
24: It produces a series of functions call `get_attr_...', one for each
25: attribute. Each of these is given the rtx for an insn and returns a member
26: of the enum for the attribute.
27:
28: These subroutines have the form of a `switch' on the INSN_CODE (via
29: `recog_memoized'). Each case either returns a constant attribute value
30: or a value that depends on tests on other attributes, the form of
31: operands, or some random C expression (encoded with a SYMBOL_REF
32: expression).
33:
34: If the attribute `alternative', or a random C expression is present,
35: `constrain_operands' is called. If either of these cases of a reference to
36: an operand is found, `insn_extract' is called.
37:
38: The special attribute `length' is also recognized. For this operand,
39: expressions involving the address of an operand or the current insn,
40: (address (pc)), are valid. In this case, an initial pass is made to
41: set all lengths that do not depend on address. Those that do are set to
42: the maximum length. Then each insn that depends on an address is checked
43: and possibly has its length changed. The process repeats until no further
44: changed are made. The resulting lengths are saved for use by
45: `get_attr_length'.
46:
47: Internal attributes are defined to handle DEFINE_DELAY and
48: DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
49:
50: This program works by keeping a list of possible values for each attribute.
51: These include the basic attribute choices, default values for attribute, and
52: all derived quantities.
53:
54: As the description file is read, the definition for each insn is saved in a
55: `struct insn_def'. When the file reading is complete, a `struct insn_ent'
56: is created for each insn and chained to the corresponding attribute value,
57: either that specified, or the default.
58:
59: An optimization phase is then run. This simplifies expressions for each
60: insn. EQ_ATTR tests are resolved, whenever possible, to a test that
61: indicates when the attribute has the specified value for the insn. This
62: avoids recursive calls during compilation.
63:
64: The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
65: definitions is to create arbitrarily complex expressions and have the
66: optimization simplify them.
67:
68: Once optimization is complete, any required routines and definitions
69: will be written. */
70:
71: #include <stdio.h>
72: #include "config.h"
73: #include "rtl.h"
74: #include "obstack.h"
75: #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
76:
77: static struct obstack obstack;
78: struct obstack *rtl_obstack = &obstack;
79:
80: #define obstack_chunk_alloc xmalloc
81: #define obstack_chunk_free free
82:
83: extern void free ();
84:
85: static void fatal ();
86: void fancy_abort ();
87:
88: /* Define structures used to record attributes and values. */
89:
90: /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
91: encountered, we store all the relevant information into a
92: `struct insn_def'. This is done to allow attribute definitions to occur
93: anywhere in the file. */
94:
95: struct insn_def
96: {
97: int insn_code; /* Instruction number. */
98: int insn_index; /* Expression numer in file, for errors. */
99: struct insn_def *next; /* Next insn in chain. */
100: rtx def; /* The DEFINE_... */
101: int num_alternatives; /* Number of alternatives. */
102: int vec_idx; /* Index of attribute vector in `def'. */
103: };
104:
105: /* Once everything has been read in, we store in each attribute value a list
106: of insn codes that have that value. Here is the structure used for the
107: list. */
108:
109: struct insn_ent
110: {
111: int insn_code; /* Instruction number. */
112: int insn_index; /* Index of definition in file */
113: struct insn_ent *next; /* Next in chain. */
114: };
115:
116: /* Each value of an attribute (either constant or computed) is assigned a
117: structure which is used as the listhead of the insns that have that
118: value. */
119:
120: struct attr_value
121: {
122: rtx value; /* Value of attribute. */
123: struct attr_value *next; /* Next attribute value in chain. */
124: struct insn_ent *first_insn; /* First insn with this value. */
125: int num_insns; /* Number of insns with this value. */
126: int has_asm_insn; /* True if this value used for `asm' insns */
127: };
128:
129: /* Structure for each attribute. */
130:
131: struct attr_desc
132: {
133: char *name; /* Name of attribute. */
134: struct attr_desc *next; /* Next attribute. */
135: int is_numeric; /* Values of this attribute are numeric. */
136: int is_special; /* Don't call `write_attr_set'. */
137: struct attr_value *first_value; /* First value of this attribute. */
138: struct attr_value *default_val; /* Default value for this attribute. */
139: };
140:
141: /* Structure for each DEFINE_DELAY. */
142:
143: struct delay_desc
144: {
145: rtx def; /* DEFINE_DELAY expression. */
146: struct delay_desc *next; /* Next DEFINE_DELAY. */
147: int num; /* Number of DEFINE_DELAY, starting at 1. */
148: };
149:
150: /* Record information about each DEFINE_FUNCTION_UNIT. */
151:
152: struct function_unit_op
153: {
154: rtx condexp; /* Expression TRUE for applicable insn. */
155: struct function_unit_op *next; /* Next operation for this function unit. */
156: int num; /* Ordinal for this operation type in unit. */
157: int ready; /* Cost until data is ready. */
158: rtx busyexp; /* Expression computing conflict cost. */
159: };
160:
161: /* Record information about each function unit mentioned in a
162: DEFINE_FUNCTION_UNIT. */
163:
164: struct function_unit
165: {
166: char *name; /* Function unit name. */
167: struct function_unit *next; /* Next function unit. */
168: int num; /* Ordinal of this unit type. */
169: int multiplicity; /* Number of units of this type. */
170: int simultaneity; /* Maximum number of simultaneous insns
171: on this function unit or 0 if unlimited. */
172: rtx condexp; /* Expression TRUE for insn needing unit. */
173: rtx costexp; /* Worst-case cost as function of insn. */
174: int num_opclasses; /* Number of different operation types. */
175: struct function_unit_op *ops; /* Pointer to first operation type. */
176: int needs_conflict_function; /* Nonzero if a conflict function required. */
177: rtx default_cost; /* Conflict cost, if constant. */
178: };
179:
180: /* Listheads of above structures. */
181:
182: static struct attr_desc *attrs;
183: static struct insn_def *defs;
184: static struct delay_desc *delays;
185: static struct function_unit *units;
186:
187: /* Other variables. */
188:
189: static int insn_code_number;
190: static int insn_index_number;
191: static int got_define_asm_attributes;
192: static int must_extract;
193: static int must_constrain;
194: static int address_used;
195: static int num_delays;
196: static int have_annul_true, have_annul_false;
197: static int num_units;
198:
199: /* Used as operand to `operate_exp': */
200:
201: enum operator {PLUS_OP, MINUS_OP, OR_OP, MAX_OP};
202:
203: /* Stores, for each insn code, a bitmap that has bits on for each possible
204: alternative. */
205:
206: static int *insn_alternatives;
207:
208: /* Used to simplify expressions. */
209:
210: static rtx true_rtx, false_rtx;
211:
212: /* Used to reduce calls to `strcmp' */
213:
214: static char *alternative_name = "alternative";
215:
216: /* Simplify an expression. Only call the routine if there is something to
217: simplify. */
218: #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
219: (RTX_UNCHANGING_P (EXP) ? (EXP) \
220: : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
221:
222: /* These are referenced by rtlanal.c and hence need to be defined somewhere.
223: They won't actually be used. */
224:
225: rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
226:
227: static rtx check_attr_test ();
228: static void check_attr_value ();
229: static rtx convert_set_attr_alternative ();
230: static rtx convert_set_attr ();
231: static void check_defs ();
232: static rtx make_canonical ();
233: static struct attr_value *get_attr_value ();
234: static void expand_delays ();
235: static rtx operate_exp ();
236: static void expand_units ();
237: static void fill_attr ();
238: static rtx substitute_address ();
239: static void make_length_attrs ();
240: static rtx identity_fn ();
241: static rtx zero_fn ();
242: static rtx one_fn ();
243: static rtx max_fn ();
244: static rtx simplify_cond ();
245: static void remove_insn_ent ();
246: static void insert_insn_ent ();
247: static rtx insert_right_side ();
248: static rtx make_alternative_compare ();
249: static int compute_alternative_mask ();
250: static rtx evaluate_eq_attr ();
251: static rtx simplify_and_tree ();
252: static rtx simplify_or_tree ();
253: static rtx simplify_test_exp ();
254: static void optimize_attrs ();
255: static void gen_attr ();
256: static int count_alternatives ();
257: static int compares_alternatives_p ();
258: static int contained_in_p ();
259: static void gen_insn ();
260: static void gen_delay ();
261: static void gen_unit ();
262: static void write_test_expr ();
263: static int max_attr_value ();
264: static void walk_attr_value ();
265: static void write_attr_get ();
266: static rtx eliminate_known_true ();
267: static void write_attr_set ();
268: static void write_attr_case ();
269: static void write_attr_value ();
270: static void write_attr_valueq ();
271: static void write_upcase ();
272: static void write_indent ();
273: static void write_eligible_delay ();
274: static void write_function_unit_info ();
275: static int n_comma_elts ();
276: static char *next_comma_elt ();
277: static struct attr_desc *find_attr ();
278: static void make_internal_attr ();
279: static struct attr_value *find_most_used ();
280: static rtx find_single_value ();
281: static rtx make_numeric_value ();
282: char *xrealloc ();
283: char *xmalloc ();
284: static void fatal ();
285:
286: /* Given a test expression for an attribute, ensure it is validly formed.
287: Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
288: and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
289: test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
290:
291: Update the string address in EQ_ATTR expression to be the same used
292: in the attribute (or `alternative_name') to speed up subsequent
293: `find_attr' calls and eliminate most `strcmp' calls.
294:
295: Return the new expression, if any. */
296:
297: static rtx
298: check_attr_test (exp)
299: rtx exp;
300: {
301: struct attr_desc *attr;
302: struct attr_value *av;
303: char *name_ptr, *p;
304: rtx orexp, newexp;
305:
306: switch (GET_CODE (exp))
307: {
308: case EQ_ATTR:
309: /* Handle negation test. */
310: if (XSTR (exp, 1)[0] == '!')
311: {
312: XSTR(exp, 1) = &XSTR(exp, 1)[1];
313: newexp = rtx_alloc (NOT);
314: XEXP (newexp, 0) = exp;
315:
316: return check_attr_test (newexp);
317: }
318:
319: else if (n_comma_elts (XSTR (exp, 1)) == 1)
320: {
321: attr = find_attr (XEXP (exp, 0), 0);
322: if (attr == NULL)
323: {
324: if (! strcmp (XSTR (exp, 0), "alternative"))
325: {
326: XSTR (exp, 0) = alternative_name;
327: /* This can't be simplified any further. */
328: RTX_UNCHANGING_P (exp) = 1;
329: return exp;
330: }
331: else
332: fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
333: }
334:
335: XSTR (exp, 0) = attr->name;
336:
337: if (attr->is_numeric)
338: {
339: for (p = XSTR (exp, 1); *p; p++)
340: if (*p < '0' || *p > '9')
341: fatal ("Attribute `%s' takes only numeric values",
342: XEXP (exp, 0));
343: }
344: else
345: {
346: for (av = attr->first_value; av; av = av->next)
347: if (GET_CODE (av->value) == CONST_STRING
348: && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
349: break;
350:
351: if (av == NULL)
352: fatal ("Unknown value `%s' for `%s' attribute",
353: XEXP (exp, 1), XEXP (exp, 0));
354: }
355: }
356: else
357: {
358: /* Make an IOR tree of the possible values. */
359: orexp = false_rtx;
360: name_ptr = XSTR (exp, 1);
361: while ((p = next_comma_elt (&name_ptr)) != NULL)
362: {
363: newexp = rtx_alloc (EQ_ATTR);
364: XSTR (newexp, 0) = XSTR (exp, 0);
365: XSTR (newexp, 1) = p;
366: orexp = insert_right_side (IOR, orexp, newexp, -2);
367: }
368:
369: return check_attr_test (orexp);
370: }
371: break;
372:
373: case CONST_INT:
374: /* Either TRUE or FALSE. */
375: if (XINT (exp, 0))
376: return true_rtx;
377: else
378: return false_rtx;
379:
380: case IOR:
381: case AND:
382: XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
383: XEXP (exp, 1) = check_attr_test (XEXP (exp, 1));
384: break;
385:
386: case NOT:
387: XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
388: break;
389:
390: case MATCH_OPERAND:
391: case LE: case LT: case GT: case GE:
392: case LEU: case LTU: case GTU: case GEU:
393: case NE: case EQ:
394: /* These cases can't be simplified. */
395: RTX_UNCHANGING_P (exp) = 1;
396: break;
397:
398: default:
399: fatal ("RTL operator \"%s\" not valid in attribute test",
400: GET_RTX_NAME (GET_CODE (exp)));
401: }
402:
403: return exp;
404: }
405:
406: /* Given an expression, ensure that it is validly formed and that all named
407: attribute values are valid for the given attribute. Issue a fatal error
408: if not. If no attribute is specified, assume a numeric attribute. */
409:
410: static void
411: check_attr_value (exp, attr)
412: rtx exp;
413: struct attr_desc *attr;
414: {
415: struct attr_value *av;
416: char *p;
417: int i;
418:
419: switch (GET_CODE (exp))
420: {
421: case CONST_INT:
422: if (attr && ! attr->is_numeric)
423: fatal ("CONST_INT not valid for non-numeric `%s' attribute",
424: attr->name);
425:
426: if (INTVAL (exp) < 0)
427: fatal ("Negative numeric value specified for `%s' attribute",
428: attr->name);
429:
430: break;
431:
432: case CONST_STRING:
433: if (! strcmp (XSTR (exp, 0), "*"))
434: break;
435:
436: if (attr == 0 || attr->is_numeric)
437: {
438: for (p = XSTR (exp, 0); *p; p++)
439: if (*p > '9' || *p < '0')
440: fatal ("Non-numeric value for numeric `%s' attribute",
441: attr ? "internal" : attr->name);
442: break;
443: }
444:
445: for (av = attr->first_value; av; av = av->next)
446: if (GET_CODE (av->value) == CONST_STRING
447: && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
448: break;
449:
450: if (av == NULL)
451: fatal ("Unknown value `%s' for `%s' attribute",
452: XSTR (exp, 0), attr ? "internal" : attr->name);
453:
454: return;
455:
456: case IF_THEN_ELSE:
457: XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
458: check_attr_value (XEXP (exp, 1), attr);
459: check_attr_value (XEXP (exp, 2), attr);
460: return;
461:
462: case COND:
463: if (XVECLEN (exp, 0) % 2 != 0)
464: fatal ("First operand of COND must have even length");
465:
466: for (i = 0; i < XVECLEN (exp, 0); i += 2)
467: {
468: XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i));
469: check_attr_value (XVECEXP (exp, 0, i + 1), attr);
470: }
471:
472: check_attr_value (XEXP (exp, 1), attr);
473: return;
474:
475: default:
476: fatal ("Illegal operation `%s' for attribute value",
477: GET_RTX_NAME (GET_CODE (exp)));
478: }
479: }
480:
481: /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
482: It becomes a COND with each test being (eq_attr "alternative "n") */
483:
484: static rtx
485: convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
486: rtx exp;
487: int num_alt;
488: int insn_code, insn_index;
489: {
490: rtx newexp;
491: rtx condexp;
492: int i;
493:
494: if (XVECLEN (exp, 1) != num_alt)
495: fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
496: insn_index);
497:
498: /* Make a COND with all tests but the last. Select the last value via the
499: default. */
500: condexp = rtx_alloc (COND);
501: XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
502:
503: for (i = 0; i < num_alt - 1; i++)
504: {
505: XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
506: XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
507: XSTR (XVECEXP (condexp, 0, 2 * i), 1) = (char *) xmalloc (3);
508: sprintf (XSTR (XVECEXP (condexp, 0, 2 * i), 1), "%d", i);
509: XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
510: }
511:
512: XEXP (condexp, 1) = XVECEXP (exp, 1, i);
513:
514: newexp = rtx_alloc (SET);
515: XEXP (newexp, 0) = rtx_alloc (ATTR);
516: XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
517: XEXP (newexp, 1) = condexp;
518:
519: return newexp;
520: }
521:
522: /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
523: list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
524:
525: static rtx
526: convert_set_attr (exp, num_alt, insn_code, insn_index)
527: rtx exp;
528: int num_alt;
529: int insn_code, insn_index;
530: {
531: rtx newexp;
532: char *name_ptr;
533: char *p;
534: int n;
535:
536: /* See how many alternative specified. */
537: n = n_comma_elts (XSTR (exp, 1));
538: if (n == 1)
539: {
540: newexp = rtx_alloc (SET);
541: XEXP (newexp, 0) = rtx_alloc (ATTR);
542: XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
543: XEXP (newexp, 1) = rtx_alloc (CONST_STRING);
544: XSTR (XEXP (newexp, 1), 0) = XSTR (exp, 1);
545:
546: return newexp;
547: }
548:
549: newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
550: XSTR (newexp, 0) = XSTR (exp, 0);
551: XVEC (newexp, 1) = rtvec_alloc (n);
552:
553: /* Process each comma-separated name. */
554: name_ptr = XSTR (exp, 1);
555: n = 0;
556: while ((p = next_comma_elt (&name_ptr)) != NULL)
557: {
558: XVECEXP (newexp, 1, n) = rtx_alloc (CONST_STRING);
559: XSTR (XVECEXP (newexp, 1, n++), 0) = p;
560: }
561:
562: return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
563: }
564:
565: /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
566: and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
567: expressions. */
568:
569: static void
570: check_defs ()
571: {
572: struct insn_def *id;
573: struct attr_desc *attr;
574: int i;
575: rtx value;
576:
577: for (id = defs; id; id = id->next)
578: {
579: if (XVEC (id->def, id->vec_idx) == NULL)
580: continue;
581:
582: for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
583: {
584: value = XVECEXP (id->def, id->vec_idx, i);
585: switch (GET_CODE (value))
586: {
587: case SET:
588: if (GET_CODE (XEXP (value, 0)) != ATTR)
589: fatal ("Bad attribute set in pattern %d", id->insn_index);
590: break;
591:
592: case SET_ATTR_ALTERNATIVE:
593: value = convert_set_attr_alternative (value,
594: id->num_alternatives,
595: id->insn_code,
596: id->insn_index);
597: break;
598:
599: case SET_ATTR:
600: value = convert_set_attr (value, id->num_alternatives,
601: id->insn_code, id->insn_index);
602: break;
603:
604: default:
605: fatal ("Invalid attribute code `%s' for pattern %d",
606: GET_RTX_NAME (GET_CODE (value)), id->insn_index);
607: }
608:
609: if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
610: fatal ("Unknown attribute `%s' for pattern number %d",
611: XSTR (XEXP (value, 0), 0), id->insn_index);
612:
613: XVECEXP (id->def, id->vec_idx, i) = value;
614: check_attr_value (XEXP (value, 1), attr);
615: }
616: }
617: }
618:
619: /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
620: expressions by converting them into a COND. This removes cases from this
621: program. Also, replace an attribute value of "*" with the default attribute
622: value. */
623:
624: static rtx
625: make_canonical (attr, exp)
626: struct attr_desc *attr;
627: rtx exp;
628: {
629: int i;
630: rtx newexp;
631:
632: switch (GET_CODE (exp))
633: {
634: case CONST_INT:
635: exp = make_numeric_value (INTVAL (exp));
636: break;
637:
638: case CONST_STRING:
639: if (! strcmp (XSTR (exp, 0), "*"))
640: {
641: if (attr == 0 || attr->default_val == 0)
642: fatal ("(attr_value \"*\") used in invalid context.");
643: exp = attr->default_val->value;
644: }
645:
646: break;
647:
648: case IF_THEN_ELSE:
649: newexp = rtx_alloc (COND);
650: XVEC (newexp, 0) = rtvec_alloc (2);
651: XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
652: XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
653:
654: XEXP (newexp, 1) = XEXP (exp, 2);
655:
656: exp = newexp;
657: /* Fall through to COND case since this is now a COND. */
658:
659: case COND:
660: /* First, check for degenerate COND. */
661: if (XVECLEN (exp, 0) == 0)
662: return make_canonical (attr, XEXP (exp, 1));
663:
664: for (i = 0; i < XVECLEN (exp, 0); i += 2)
665: XVECEXP (exp, 0, i + 1)
666: = make_canonical (attr, XVECEXP (exp, 0, i + 1));
667:
668: XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
669: break;
670: }
671:
672: return exp;
673: }
674:
675: /* Given a value and an attribute description, return a `struct attr_value *'
676: that represents that value. This is either an existing structure, if the
677: value has been previously encountered, or a newly-created structure.
678:
679: `insn_code' is the code of an insn whose attribute has the specified
680: value (-2 if not processing an insn). We ensure that all insns for
681: a given value have the same number of alternatives if the value checks
682: alternatives. */
683:
684: static struct attr_value *
685: get_attr_value (value, attr, insn_code)
686: rtx value;
687: struct attr_desc *attr;
688: int insn_code;
689: {
690: struct attr_value *av;
691: int num_alt = 0;
692:
693: value = make_canonical (attr, value);
694: if (compares_alternatives_p (value))
695: {
696: if (insn_code < 0 || insn_alternatives == NULL)
697: fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
698: else
699: num_alt = insn_alternatives[insn_code];
700: }
701:
702: for (av = attr->first_value; av; av = av->next)
703: if (rtx_equal_p (value, av->value)
704: && (num_alt == 0 || av->first_insn == NULL
705: || insn_alternatives[av->first_insn->insn_code]))
706: return av;
707:
708: av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
709: av->value = value;
710: av->next = attr->first_value;
711: attr->first_value = av;
712: av->first_insn = NULL;
713: av->num_insns = 0;
714: av->has_asm_insn = 0;
715:
716: return av;
717: }
718:
719: /* After all DEFINE_DELAYs have been read in, create internal attributes
720: to generate the required routines.
721:
722: First, we compute the number of delay slots for each insn (as a COND of
723: each of the test expressions in DEFINE_DELAYs). Then, if more than one
724: delay type is specified, we compute a similar function giving the
725: DEFINE_DELAY ordinal for each insn.
726:
727: Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
728: tells whether a given insn can be in that delay slot.
729:
730: Normal attrbute filling and optimization expands these to contain the
731: information needed to handle delay slots. */
732:
733: static void
734: expand_delays ()
735: {
736: struct delay_desc *delay;
737: rtx condexp;
738: rtx newexp;
739: int i;
740: char *p;
741:
742: /* First, generate data for `num_delay_slots' function. */
743:
744: condexp = rtx_alloc (COND);
745: XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
746: XEXP (condexp, 1) = make_numeric_value (0);
747:
748: for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
749: {
750: XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
751: XVECEXP (condexp, 0, i + 1)
752: = make_numeric_value (XVECLEN (delay->def, 1) / 3);
753: }
754:
755: make_internal_attr ("*num_delay_slots", condexp, 0);
756:
757: /* If more than one delay type, do the same for computing the delay type. */
758: if (num_delays > 1)
759: {
760: condexp = rtx_alloc (COND);
761: XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
762: XEXP (condexp, 1) = make_numeric_value (0);
763:
764: for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
765: {
766: XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
767: XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
768: }
769:
770: make_internal_attr ("*delay_type", condexp, 1);
771: }
772:
773: /* For each delay possibility and delay slot, compute an eligability
774: attribute for non-anulled insns and for each type of annulled (annul
775: if true and annul if false). */
776: for (delay = delays; delay; delay = delay->next)
777: {
778: for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
779: {
780: newexp = rtx_alloc (IF_THEN_ELSE);
781: condexp = XVECEXP (delay->def, 1, i);
782: if (condexp == 0) condexp = false_rtx;
783: XEXP (newexp, 0) = condexp;
784: XEXP (newexp, 1) = make_numeric_value (1);
785: XEXP (newexp, 2) = make_numeric_value (0);
786:
787: p = (char *) xmalloc (13);
788: sprintf (p, "*delay_%d_%d", delay->num, i / 3);
789: make_internal_attr (p, newexp, 1);
790:
791: if (have_annul_true)
792: {
793: newexp = rtx_alloc (IF_THEN_ELSE);
794: condexp = XVECEXP (delay->def, 1, i + 1);
795: if (condexp == 0) condexp = false_rtx;
796: XEXP (newexp, 0) = condexp;
797: XEXP (newexp, 1) = make_numeric_value (1);
798: XEXP (newexp, 2) = make_numeric_value (0);
799: p = (char *) xmalloc (18);
800: sprintf (p, "*annul_true_%d_%d", delay->num, i / 3);
801: make_internal_attr (p, newexp, 1);
802: }
803:
804: if (have_annul_false)
805: {
806: newexp = rtx_alloc (IF_THEN_ELSE);
807: condexp = XVECEXP (delay->def, 1, i + 2);
808: if (condexp == 0) condexp = false_rtx;
809: XEXP (newexp, 0) = condexp;
810: XEXP (newexp, 1) = make_numeric_value (1);
811: XEXP (newexp, 2) = make_numeric_value (0);
812: p = (char *) xmalloc (18);
813: sprintf (p, "*annul_false_%d_%d", delay->num, i / 3);
814: make_internal_attr (p, newexp, 1);
815: }
816: }
817: }
818: }
819:
820: /* This function is given a left and right side expression and an operator.
821: Each side is a conditional expression, each alternative of which has a
822: numerical value. The function returns another conditional expression
823: which, for every possible set of condition values, returns a value that is
824: the operator applied to the values of the two sides.
825:
826: Since this is called early, it must also support IF_THEN_ELSE. */
827:
828: static rtx
829: operate_exp (op, left, right)
830: enum operator op;
831: rtx left, right;
832: {
833: int left_value, right_value;
834: rtx newexp;
835: int i;
836:
837: /* If left is a string, apply operator to it and the right side. */
838: if (GET_CODE (left) == CONST_STRING)
839: {
840: /* If right is also a string, just perform the operation. */
841: if (GET_CODE (right) == CONST_STRING)
842: {
843: left_value = atoi (XSTR (left, 0));
844: right_value = atoi (XSTR (right, 0));
845: switch (op)
846: {
847: case PLUS_OP:
848: i = left_value + right_value;
849: break;
850:
851: case MINUS_OP:
852: i = left_value - right_value;
853: break;
854:
855: case OR_OP:
856: i = left_value | right_value;
857: break;
858:
859: case MAX_OP:
860: if (left_value > right_value)
861: i = left_value;
862: else
863: i = right_value;
864: break;
865:
866: default:
867: abort ();
868: }
869:
870: return make_numeric_value (i);
871: }
872: else if (GET_CODE (right) == IF_THEN_ELSE)
873: {
874: /* Apply recursively to all values within. */
875: newexp = rtx_alloc (IF_THEN_ELSE);
876: XEXP (newexp, 0) = XEXP (right, 0);
877: XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
878: XEXP (newexp, 2) = operate_exp (op, left, XEXP (right, 2));
879:
880: return newexp;
881: }
882: else if (GET_CODE (right) == COND)
883: {
884: newexp = rtx_alloc (COND);
885: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
886: for (i = 0; i < XVECLEN (right, 0); i += 2)
887: {
888: XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
889: XVECEXP (newexp, 0, i + 1)
890: = operate_exp (op, left, XVECEXP (right, 0, i + 1));
891: }
892:
893: XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
894:
895: return newexp;
896: }
897: else
898: fatal ("Badly formed attribute value");
899: }
900:
901: /* Otherwise, do recursion the other way. */
902: else if (GET_CODE (left) == IF_THEN_ELSE)
903: {
904: newexp = rtx_alloc (IF_THEN_ELSE);
905: XEXP (newexp, 0) = XEXP (left, 0);
906: XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
907: XEXP (newexp, 2) = operate_exp (op, XEXP (left, 2), right);
908:
909: return newexp;
910: }
911:
912: else if (GET_CODE (left) == COND)
913: {
914: newexp = rtx_alloc (COND);
915: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
916: for (i = 0; i < XVECLEN (left, 0); i += 2)
917: {
918: XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
919: XVECEXP (newexp, 0, i + 1)
920: = operate_exp (op, XVECEXP (left, 0, i + 1), right);
921: }
922:
923: XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
924:
925: return newexp;
926: }
927:
928: else
929: fatal ("Badly formed attribute value.");
930: /* NOTREACHED */
931: return NULL;
932: }
933:
934: /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
935: construct a number of attributes.
936:
937: The first produces a function `function_units_used' which is given an
938: insn and produces a mask showing which function units are required for
939: the execution of that insn.
940:
941: The second produces a function `result_ready_cost' which is used to
942: determine the time that the result of an insn will be ready and hence
943: a worst-case schedule.
944:
945: Both of these produce quite complex expressions which are then set as the
946: default value of internal attributes. Normal attribute simplification
947: should produce reasonable expressions.
948:
949: For each unit, a `<name>_unit_ready_cost' function will take an
950: insn and give the delay until that unit will be ready with the result
951: and a `<name>_unit_busy_delay' function is given an insn already
952: executing on the unit and a candidate to execute and will give the
953: cost from the time the executing insn started until the candidate
954: can start (ignore limitations on the number of simultaneous insns). */
955:
956: static void
957: expand_units ()
958: {
959: struct function_unit *unit;
960: struct function_unit_op *op;
961: rtx unitsmask;
962: rtx readycost;
963: rtx newexp;
964: char *str;
965:
966: /* Initially, cost and masks are zero. */
967: unitsmask = readycost = make_numeric_value (0);
968:
969: /* Set up a conditional for costs and unit mask. */
970: newexp = rtx_alloc (IF_THEN_ELSE);
971: XEXP (newexp, 2) = make_numeric_value (0);
972:
973: /* For each unit, insert its contribution to the above three values. */
974: for (unit = units; unit; unit = unit->next)
975: {
976: /* An expression that computes the ready cost for this unit. */
977: rtx readyexp = rtx_alloc (COND);
978: /* An expression that maps insns to operation number for conflicts. */
979: rtx caseexp = rtx_alloc (COND);
980:
981: XVEC (readyexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
982: XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
983:
984: for (op = unit->ops; op; op = op->next)
985: {
986: str = (char *) xmalloc (strlen (unit->name) + 11);
987:
988: /* Validate the expressions we were given for the conditions
989: and busy cost. Then make an attribute for use in the conflict
990: function. */
991: op->condexp = check_attr_test (op->condexp);
992: check_attr_value (op->busyexp, 0);
993: sprintf (str, "*%s_case_%d", unit->name, op->num);
994: make_internal_attr (str, make_canonical (0, op->busyexp));
995:
996: /* Make our adjustment to the two COND's being computed. If we are
997: the last operation class, place our values into the default of
998: the COND. */
999: if (op->num == unit->num_opclasses - 1)
1000: {
1001: XEXP (readyexp, 1) = make_numeric_value (op->ready);
1002: XEXP (caseexp, 1) = make_numeric_value (op->num);
1003: }
1004: else
1005: {
1006: XVECEXP (readyexp, 0, op->num * 2) = op->condexp;
1007: XVECEXP (readyexp, 0, op->num * 2 + 1)
1008: = make_numeric_value (op->ready);
1009: XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
1010: XVECEXP (caseexp, 0, op->num * 2 + 1)
1011: = make_numeric_value (op->num);
1012: }
1013: }
1014:
1015: /* Make an attribute for the case number and ready delay. */
1016: str = (char *) xmalloc (strlen (unit->name) + 8);
1017: sprintf (str, "*%s_cases", unit->name);
1018: make_internal_attr (str, caseexp, 1);
1019:
1020: str = (char *) xmalloc (strlen (unit->name) + 20);
1021: sprintf (str, "*%s_unit_ready_cost", unit->name);
1022: make_internal_attr (str, readyexp, 0);
1023:
1024: /* Merge this function unit into the ready cost and unit mask
1025: attributes. */
1026: XEXP (newexp, 0) = check_attr_test (unit->condexp);
1027: XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1028: unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1029:
1030: XEXP (newexp, 1) = readyexp;
1031: readycost = operate_exp (MAX_OP, readycost, newexp);
1032: }
1033:
1034: make_internal_attr ("*function_units_used", unitsmask, 0);
1035: make_internal_attr ("*result_ready_cost", readycost, 0);
1036: }
1037:
1038: /* Once all attributes and insns have been read and checked, we construct for
1039: each attribute value a list of all the insns that have that value for
1040: the attribute. */
1041:
1042: static void
1043: fill_attr (attr)
1044: struct attr_desc *attr;
1045: {
1046: struct attr_value *av;
1047: struct insn_ent *ie;
1048: struct insn_def *id;
1049: int i;
1050: rtx value;
1051:
1052: for (id = defs; id; id = id->next)
1053: {
1054: /* If no value is specified for this insn for this attribute, use the
1055: default. */
1056: value = NULL;
1057: if (XVEC (id->def, id->vec_idx))
1058: for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1059: if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1060: attr->name))
1061: value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1062:
1063: if (value == NULL)
1064: av = attr->default_val;
1065: else
1066: av = get_attr_value (value, attr, id->insn_code);
1067:
1068: ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1069: ie->insn_code = id->insn_code;
1070: ie->insn_index = id->insn_code;
1071: insert_insn_ent (av, ie);
1072: }
1073: }
1074:
1075: /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1076: test that checks relative positions of insns (uses MATCH_DUP or PC).
1077: If so, replace it with what is obtained by passing the expression to
1078: ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1079: recursively on each value (including the default value). Otherwise,
1080: return the value returned by NO_ADDRESS_FN applied to EXP. */
1081:
1082: static rtx
1083: substitute_address (exp, no_address_fn, address_fn)
1084: rtx exp;
1085: rtx (*no_address_fn) ();
1086: rtx (*address_fn) ();
1087: {
1088: int i;
1089: rtx newexp;
1090:
1091: if (GET_CODE (exp) == COND)
1092: {
1093: /* See if any tests use addresses. */
1094: address_used = 0;
1095: for (i = 0; i < XVECLEN (exp, 0); i += 2)
1096: walk_attr_value (XVECEXP (exp, 0, i));
1097:
1098: if (address_used)
1099: return (*address_fn) (exp);
1100:
1101: /* Make a new copy of this COND, replacing each element. */
1102: newexp = rtx_alloc (COND);
1103: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1104: for (i = 0; i < XVECLEN (exp, 0); i += 2)
1105: {
1106: XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1107: XVECEXP (newexp, 0, i + 1)
1108: = substitute_address (XVECEXP (exp, 0, i + 1),
1109: no_address_fn, address_fn);
1110: }
1111:
1112: XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1113: no_address_fn, address_fn);
1114:
1115: return newexp;
1116: }
1117:
1118: else if (GET_CODE (exp) == IF_THEN_ELSE)
1119: {
1120: address_used = 0;
1121: walk_attr_value (XEXP (exp, 0));
1122: if (address_used)
1123: return (*address_fn) (exp);
1124:
1125: newexp = rtx_alloc (IF_THEN_ELSE);
1126: XEXP (newexp, 0) = substitute_address (XEXP (exp, 0),
1127: no_address_fn, address_fn);
1128: XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1129: no_address_fn, address_fn);
1130: XEXP (newexp, 2) = substitute_address (XEXP (exp, 2),
1131: no_address_fn, address_fn);
1132:
1133: return newexp;
1134: }
1135:
1136: return (*no_address_fn) (exp);
1137: }
1138:
1139: /* Make new attributes from the `length' attribute. The following are made,
1140: each corresponding to a function called from `shorten_branches' or
1141: `get_attr_length':
1142:
1143: *insn_default_length This is the length of the insn to be returned
1144: by `get_attr_length' before `shorten_branches'
1145: has been called. In each case where the length
1146: depends on relative addresses, the largest
1147: possible is used. This routine is also used
1148: to compute the initial size of the insn.
1149:
1150: *insn_variable_length_p This returns 1 if the insn's length depends
1151: on relative addresses, zero otherwise.
1152:
1153: *insn_current_length This is only called when it is known that the
1154: insn has a variable length and returns the
1155: current length, based on relative addresses.
1156: */
1157:
1158: static void
1159: make_length_attrs ()
1160: {
1161: static char *new_names[] = {"*insn_default_length",
1162: "*insn_variable_length_p",
1163: "*insn_current_length"};
1164: static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
1165: static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
1166: int i;
1167: struct attr_desc *length_attr, *new_attr;
1168: struct attr_value *av, *new_av;
1169: struct insn_ent *ie, *new_ie;
1170:
1171: /* See if length attribute is defined. If so, it must be numeric. Make
1172: it special so we don't output anything for it. */
1173: length_attr = find_attr ("length", 0);
1174: if (length_attr == 0)
1175: return;
1176:
1177: if (! length_attr->is_numeric)
1178: fatal ("length attribute must be numeric.");
1179:
1180: length_attr->is_special = 1;
1181:
1182: /* Make each new attribute, in turn. */
1183: for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
1184: {
1185: make_internal_attr (new_names[i],
1186: substitute_address (length_attr->default_val->value,
1187: no_address_fn[i], address_fn[i]),
1188: 0);
1189: new_attr = find_attr (new_names[i], 0);
1190: for (av = length_attr->first_value; av; av = av->next)
1191: for (ie = av->first_insn; ie; ie = ie->next)
1192: {
1193: new_av = get_attr_value (substitute_address (av->value,
1194: no_address_fn[i],
1195: address_fn[i]),
1196: new_attr, ie->insn_code);
1197: new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1198: new_ie->insn_code = ie->insn_code;
1199: new_ie->insn_index = ie->insn_index;
1200: insert_insn_ent (new_av, new_ie);
1201: }
1202: }
1203: }
1204:
1205: /* Utility functions called from above routine. */
1206:
1207: static rtx
1208: identity_fn (exp)
1209: rtx exp;
1210: {
1211: return exp;
1212: }
1213:
1214: static rtx
1215: zero_fn (exp)
1216: rtx exp;
1217: {
1218: return make_numeric_value (0);
1219: }
1220:
1221: static rtx
1222: one_fn (exp)
1223: rtx exp;
1224: {
1225: return make_numeric_value (1);
1226: }
1227:
1228: static rtx
1229: max_fn (exp)
1230: rtx exp;
1231: {
1232: return make_numeric_value (max_attr_value (exp));
1233: }
1234:
1235: /* Take a COND expression and see if any of the conditions in it can be
1236: simplified. If any are known true or known false for the particular insn
1237: code, the COND can be further simplified.
1238:
1239: Also call ourselves on any COND operations that are values of this COND.
1240:
1241: We only do the first replacement found directly and call ourselves
1242: recursively for subsequent replacements. */
1243:
1244: static rtx
1245: simplify_cond (exp, insn_code, insn_index)
1246: rtx exp;
1247: int insn_code, insn_index;
1248: {
1249: int i, j;
1250: rtx newtest;
1251: rtx value;
1252: rtx newexp = exp;
1253:
1254: for (i = 0; i < XVECLEN (exp, 0); i += 2)
1255: {
1256: newtest = SIMPLIFY_TEST_EXP (XVECEXP (exp, 0, i), insn_code, insn_index);
1257: if (newtest == true_rtx)
1258: {
1259: /* Make a new COND with any previous conditions and the value for
1260: this pair as the default value. */
1261: newexp = rtx_alloc (COND);
1262: XVEC (newexp, 0) = rtvec_alloc (i);
1263: for (j = 0; j < i; j++)
1264: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1265:
1266: XEXP (newexp, 1) = XVECEXP (exp, 0, i + 1);
1267: break;
1268: }
1269:
1270: else if (newtest == false_rtx)
1271: {
1272: /* Build a new COND without this test. */
1273: newexp = rtx_alloc (COND);
1274: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1275: for (j = 0; j < i; j++)
1276: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1277:
1278: for (j = i; j < XVECLEN (newexp, 0); j++)
1279: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1280:
1281: XEXP (newexp, 1) = XEXP (exp, 1);
1282: break;
1283: }
1284:
1285: else if (newtest != XVECEXP (exp, 0, i))
1286: {
1287: newexp = rtx_alloc (COND);
1288: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1289: for (j = 0; j < XVECLEN (exp, 0); j++)
1290: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1291: XEXP (newexp, 1) = XEXP (exp, 1);
1292:
1293: XVECEXP (newexp, 0, i) = newtest;
1294: break;
1295: }
1296:
1297: /* See if this value may need simplification. */
1298: if (GET_CODE (XVECEXP (exp, 0, i + 1)) == COND)
1299: {
1300: value = simplify_cond (XVECEXP (exp, 0, i + 1),
1301: insn_code, insn_index);
1302: if (value != XVECEXP (exp, 0, i + 1))
1303: {
1304: newexp = rtx_alloc (COND);
1305: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1306: for (j = 0; j < XVECLEN (exp, 0); j++)
1307: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1308: XEXP (newexp, 1) = XEXP (exp, 1);
1309:
1310: XVECEXP (newexp, 0, i + 1) = value;
1311: break;
1312: }
1313: }
1314:
1315: /* If this is the last condition in a COND and our value is the same
1316: as the default value, our test isn't needed. */
1317: if (i == XVECLEN (exp, 0) - 2
1318: && rtx_equal_p (XVECEXP (exp, 0, i + 1), XEXP (exp, 1)))
1319: {
1320: newexp = rtx_alloc (COND);
1321: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1322: for (j = 0; j < i; j++)
1323: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1324: XEXP (newexp, 1) = XEXP (exp, 1);
1325: break;
1326: }
1327:
1328: /* If this value and the value for the next test are the same, merge the
1329: tests. */
1330: else if (i != XVECLEN (exp, 0) - 2
1331: && rtx_equal_p (XVECEXP (exp, 0, i + 1),
1332: XVECEXP (exp, 0, i + 3)))
1333: {
1334: newexp = rtx_alloc (COND);
1335: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1336: for (j = 0; j < i; j++)
1337: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1338:
1339: XVECEXP (newexp, 0, j)
1340: = insert_right_side (IOR, XVECEXP (exp, 0, i),
1341: XVECEXP (exp, 0, i + 2),
1342: insn_code, insn_index);
1343: XVECEXP (newexp, 0, j + 1) = XVECEXP (exp, 0, i + 1);
1344:
1345: for (j = i + 2; j < XVECLEN (newexp, 0); j++)
1346: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1347:
1348: XEXP (newexp, 1) = XEXP (exp, 1);
1349: break;
1350: }
1351: }
1352:
1353: /* See if default value needs simplification. */
1354: if (GET_CODE (XEXP (exp, 1)) == COND)
1355: {
1356: value = simplify_cond (XEXP (exp, 1), insn_code, insn_index);
1357: if (value != XEXP (exp, 1))
1358: {
1359: newexp = rtx_alloc (COND);
1360: XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1361: for (j = 0; j < XVECLEN (exp, 0); j++)
1362: XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1363: XEXP (newexp, 1) = value;
1364: }
1365: }
1366:
1367: if (exp == newexp)
1368: return exp;
1369: else if (XVECLEN (newexp, 0) == 1)
1370: return XVECEXP (newexp, 0, 0);
1371: else
1372: return simplify_cond (newexp, insn_code, insn_index);
1373: }
1374:
1375: /* Remove an insn entry from an attribute value. */
1376:
1377: static void
1378: remove_insn_ent (av, ie)
1379: struct attr_value *av;
1380: struct insn_ent *ie;
1381: {
1382: struct insn_ent *previe;
1383:
1384: if (av->first_insn == ie)
1385: av->first_insn = ie->next;
1386: else
1387: {
1388: for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1389: ;
1390: previe->next = ie->next;
1391: }
1392:
1393: av->num_insns--;
1394: if (ie->insn_code == -1)
1395: av->has_asm_insn = 0;
1396: }
1397:
1398: /* Insert an insn entry in an attribute value list. */
1399:
1400: static void
1401: insert_insn_ent (av, ie)
1402: struct attr_value *av;
1403: struct insn_ent *ie;
1404: {
1405: ie->next = av->first_insn;
1406: av->first_insn = ie;
1407: av->num_insns++;
1408: if (ie->insn_code == -1)
1409: av->has_asm_insn = 1;
1410: }
1411:
1412: /* This is a utility routine to take an expression that is a tree of either
1413: AND or IOR expressions and insert a new term. The new term will be
1414: inserted at the right side of the first node whose code does not match
1415: the root. A new node will be created with the root's code. Its left
1416: side will be the old right side and its right side will be the new
1417: term.
1418:
1419: If the `term' is itself a tree, all its leaves will be inserted. */
1420:
1421: static rtx
1422: insert_right_side (code, exp, term, insn_code, insn_index)
1423: RTX_CODE code;
1424: rtx exp;
1425: rtx term;
1426: int insn_code, insn_index;
1427: {
1428: rtx newexp;
1429:
1430: if (GET_CODE (term) == code)
1431: {
1432: exp = insert_right_side (code, exp, XEXP (term, 0),
1433: insn_code, insn_index);
1434: exp = insert_right_side (code, exp, XEXP (term, 1),
1435: insn_code, insn_index);
1436:
1437: return exp;
1438: }
1439:
1440: if (GET_CODE (exp) == code)
1441: {
1442: /* Make a copy of this expression and call recursively. */
1443: newexp = rtx_alloc (code);
1444: XEXP (newexp, 0) = XEXP (exp, 0);
1445: XEXP (newexp, 1) = insert_right_side (code, XEXP (exp, 1),
1446: term, insn_code, insn_index);
1447: }
1448: else
1449: {
1450: /* Insert the new term. */
1451: newexp = rtx_alloc (code);
1452: XEXP (newexp, 0) = exp;
1453: XEXP (newexp, 1) = term;
1454: }
1455:
1456: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1457: }
1458:
1459: /* If we have an expression which AND's a bunch of
1460: (not (eq_attrq "alternative" "n"))
1461: terms, we may have covered all or all but one of the possible alternatives.
1462: If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1463:
1464: This routine is passed an expression and either AND or IOR. It returns a
1465: bitmask indicating which alternatives are present. */
1466:
1467: static int
1468: compute_alternative_mask (exp, code)
1469: rtx exp;
1470: RTX_CODE code;
1471: {
1472: if (GET_CODE (exp) == code)
1473: return compute_alternative_mask (XEXP (exp, 0), code)
1474: | compute_alternative_mask (XEXP (exp, 1), code);
1475:
1476: else if (code == AND && GET_CODE (exp) == NOT
1477: && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1478: && XSTR (XEXP (exp, 0), 0) == alternative_name)
1479: return 1 << atoi (XSTR (XEXP (exp, 0), 1));
1480:
1481: else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1482: && XSTR (exp, 0) == alternative_name)
1483: return 1 << atoi (XSTR (exp, 1));
1484:
1485: else
1486: return 0;
1487: }
1488:
1489: /* Given I, a single-bit mask, return RTX to compare the `alternative'
1490: attribute with the value represented by that bit. */
1491:
1492: static rtx
1493: make_alternative_compare (mask)
1494: int mask;
1495: {
1496: rtx newexp;
1497: int i;
1498: char *alternative;
1499:
1500: /* Find the bit. */
1501: for (i = 0; (mask & (1 << i)) == 0; i++)
1502: ;
1503:
1504: alternative = (char *) xmalloc (3);
1505: sprintf (alternative, "%d", i);
1506:
1507: newexp = rtx_alloc (EQ_ATTR);
1508: XSTR (newexp, 0) = alternative_name;
1509: XSTR (newexp, 1) = alternative;
1510: RTX_UNCHANGING_P (newexp) = 1;
1511:
1512: return newexp;
1513: }
1514:
1515: /* If we are processing an (eq_attr "attr" "value") test, we find the value
1516: of "attr" for this insn code. From that value, we can compute a test
1517: showing when the EQ_ATTR will be true. This routine performs that
1518: computation. If a test condition involves an address, we leave the EQ_ATTR
1519: intact because addresses are only valid for the `length' attribute. */
1520:
1521: static rtx
1522: evaluate_eq_attr (exp, value, insn_code, insn_index)
1523: rtx exp;
1524: rtx value;
1525: int insn_code, insn_index;
1526: {
1527: rtx orexp, andexp;
1528: rtx right;
1529: rtx newexp;
1530: int i;
1531:
1532: if (GET_CODE (value) == CONST_STRING)
1533: {
1534: if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
1535: newexp = true_rtx;
1536: else
1537: newexp = false_rtx;
1538: }
1539: else if (GET_CODE (value) == COND)
1540: {
1541: /* We construct an IOR of all the cases for which the requested attribute
1542: value is present. Since we start with FALSE, if it is not present,
1543: FALSE will be returned.
1544:
1545: Each case is the AND of the NOT's of the previous conditions with the
1546: current condition; in the default case the current condition is TRUE.
1547:
1548: For each possible COND value, call ourselves recursively.
1549:
1550: The extra TRUE and FALSE expressions will be eliminated by another
1551: call to the simplification routine. */
1552:
1553: orexp = false_rtx;
1554: andexp = true_rtx;
1555:
1556: for (i = 0; i < XVECLEN (value, 0); i += 2)
1557: {
1558: right = insert_right_side (AND, andexp,
1559: XVECEXP (value, 0, i),
1560: insn_code, insn_index);
1561: right = insert_right_side (AND, right,
1562: evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
1563: insn_code, insn_index),
1564: insn_code, insn_index);
1565: orexp = insert_right_side (IOR, orexp, right,
1566: insn_code, insn_index);
1567:
1568: /* Add this condition into the AND expression. */
1569: newexp = rtx_alloc (NOT);
1570: XEXP (newexp, 0) = XVECEXP (value, 0, i);
1571: andexp = insert_right_side (AND, andexp, newexp,
1572: insn_code, insn_index);
1573: }
1574:
1575: /* Handle the default case. */
1576: right = insert_right_side (AND, andexp,
1577: evaluate_eq_attr (exp, XEXP (value, 1),
1578: insn_code, insn_index),
1579: insn_code, insn_index);
1580: newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
1581: }
1582: else
1583: abort ();
1584:
1585: /* If uses an address, must return original expression. */
1586:
1587: address_used = 0;
1588: walk_attr_value (newexp);
1589:
1590: if (address_used)
1591: return exp;
1592: else
1593: return newexp;
1594: }
1595:
1596: /* This routine is called when an AND of a term with a tree of AND's is
1597: encountered. If the term or its complement is present in the tree, it
1598: can be replaced with TRUE or FALSE, respectively.
1599:
1600: Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
1601: be true and hence are complementary.
1602:
1603: There is one special case: If we see
1604: (and (not (eq_attr "att" "v1"))
1605: (eq_attr "att" "v2"))
1606: this can be replaced by (eq_attr "att" "v2"). To do this we need to
1607: replace the term, not anything in the AND tree. So we pass a pointer to
1608: the term. */
1609:
1610: static rtx
1611: simplify_and_tree (exp, pterm, insn_code, insn_index)
1612: rtx exp;
1613: rtx *pterm;
1614: int insn_code, insn_index;
1615: {
1616: rtx left, right;
1617: rtx newexp;
1618: rtx temp;
1619: int left_eliminates_term, right_eliminates_term;
1620:
1621: if (GET_CODE (exp) == AND)
1622: {
1623: left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1624: right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1625: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1626: {
1627: newexp = rtx_alloc (GET_CODE (exp));
1628: XEXP (newexp, 0) = left;
1629: XEXP (newexp, 1) = right;
1630:
1631: exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1632: }
1633: }
1634:
1635: else if (GET_CODE (exp) == IOR)
1636: {
1637: /* For the IOR case, we do the same as above, except that we can
1638: only eliminate `term' if both sides of the IOR would do so. */
1639: temp = *pterm;
1640: left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1641: left_eliminates_term = (temp == true_rtx);
1642:
1643: temp = *pterm;
1644: right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1645: right_eliminates_term = (temp == true_rtx);
1646:
1647: if (left_eliminates_term && right_eliminates_term)
1648: *pterm = true_rtx;
1649:
1650: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1651: {
1652: newexp = rtx_alloc (GET_CODE (exp));
1653: XEXP (newexp, 0) = left;
1654: XEXP (newexp, 1) = right;
1655:
1656: exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1657: }
1658: }
1659:
1660: /* Check for simplifications. Do some extra checking here since this
1661: routine is called so many times. */
1662:
1663: if (exp == *pterm)
1664: return true_rtx;
1665:
1666: else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
1667: return false_rtx;
1668:
1669: else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
1670: return false_rtx;
1671:
1672: else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
1673: {
1674: if (XSTR (exp, 0) != XSTR (*pterm, 0))
1675: return exp;
1676:
1677: if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
1678: return true_rtx;
1679: else
1680: return false_rtx;
1681: }
1682:
1683: else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1684: && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
1685: {
1686: if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
1687: return exp;
1688:
1689: if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
1690: return false_rtx;
1691: else
1692: return true_rtx;
1693: }
1694:
1695: else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1696: && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
1697: {
1698: if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
1699: return exp;
1700:
1701: if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
1702: return false_rtx;
1703: else
1704: *pterm = true_rtx;
1705: }
1706:
1707: else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
1708: {
1709: if (rtx_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
1710: return true_rtx;
1711: }
1712:
1713: else if (GET_CODE (exp) == NOT)
1714: {
1715: if (rtx_equal_p (XEXP (exp, 0), *pterm))
1716: return false_rtx;
1717: }
1718:
1719: else if (GET_CODE (*pterm) == NOT)
1720: {
1721: if (rtx_equal_p (XEXP (*pterm, 0), exp))
1722: return false_rtx;
1723: }
1724:
1725: else if (rtx_equal_p (exp, *pterm))
1726: return true_rtx;
1727:
1728: return exp;
1729: }
1730:
1731: /* Similiar to `simplify_and_tree', but for IOR trees. */
1732:
1733: static rtx
1734: simplify_or_tree (exp, pterm, insn_code, insn_index)
1735: rtx exp;
1736: rtx *pterm;
1737: int insn_code, insn_index;
1738: {
1739: rtx left, right;
1740: rtx newexp;
1741: rtx temp;
1742: int left_eliminates_term, right_eliminates_term;
1743:
1744: if (GET_CODE (exp) == IOR)
1745: {
1746: left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1747: right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1748: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1749: {
1750: newexp = rtx_alloc (GET_CODE (exp));
1751: XEXP (newexp, 0) = left;
1752: XEXP (newexp, 1) = right;
1753:
1754: exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1755: }
1756: }
1757:
1758: else if (GET_CODE (exp) == AND)
1759: {
1760: /* For the AND case, we do the same as above, except that we can
1761: only eliminate `term' if both sides of the AND would do so. */
1762: temp = *pterm;
1763: left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1764: left_eliminates_term = (temp == false_rtx);
1765:
1766: temp = *pterm;
1767: right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1768: right_eliminates_term = (temp == false_rtx);
1769:
1770: if (left_eliminates_term && right_eliminates_term)
1771: *pterm = false_rtx;
1772:
1773: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1774: {
1775: newexp = rtx_alloc (GET_CODE (exp));
1776: XEXP (newexp, 0) = left;
1777: XEXP (newexp, 1) = right;
1778:
1779: exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1780: }
1781: }
1782:
1783: if (rtx_equal_p (exp, *pterm))
1784: return false_rtx;
1785:
1786: else if (GET_CODE (exp) == NOT && rtx_equal_p (XEXP (exp, 0), *pterm))
1787: return true_rtx;
1788:
1789: else if (GET_CODE (*pterm) == NOT && rtx_equal_p (XEXP (*pterm, 0), exp))
1790: return true_rtx;
1791:
1792: else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1793: && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1794: && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
1795: *pterm = false_rtx;
1796:
1797: else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1798: && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
1799: && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
1800: return false_rtx;
1801:
1802: return exp;
1803: }
1804:
1805: /* Given an expression, see if it can be simplified for a particular insn
1806: code based on the values of other attributes being tested. This can
1807: eliminate nested get_attr_... calls.
1808:
1809: Note that if an endless recursion is specified in the patterns, the
1810: optimization will loop. However, it will do so in precisely the cases where
1811: an infinite recursion loop could occur during compilation. It's better that
1812: it occurs here! */
1813:
1814: static rtx
1815: simplify_test_exp (exp, insn_code, insn_index)
1816: rtx exp;
1817: int insn_code, insn_index;
1818: {
1819: rtx left, right;
1820: struct attr_desc *attr;
1821: struct attr_value *av;
1822: struct insn_ent *ie;
1823: int i;
1824: rtx newexp = exp;
1825:
1826: switch (GET_CODE (exp))
1827: {
1828: case AND:
1829: left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1830: right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1831:
1832: /* If either side is an IOR and we have (eq_attr "alternative" ..")
1833: present on both sides, apply the distributive law since this will
1834: yield simplications. */
1835: if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
1836: && compute_alternative_mask (left, IOR)
1837: && compute_alternative_mask (right, IOR))
1838: {
1839: if (GET_CODE (left) == IOR)
1840: {
1841: rtx tem = left;
1842: left = right;
1843: right = tem;
1844: }
1845:
1846: newexp = rtx_alloc (IOR);
1847: XEXP (newexp, 0) = rtx_alloc (AND);
1848: XEXP (newexp, 1) = rtx_alloc (AND);
1849: XEXP (XEXP (newexp, 0), 0) = XEXP (XEXP (newexp, 1), 0) = left;
1850: XEXP (XEXP (newexp, 0), 1) = XEXP (right, 0);
1851: XEXP (XEXP (newexp, 1), 1) = XEXP (right, 1);
1852:
1853: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1854: }
1855:
1856: /* Try with the term on both sides. */
1857: right = simplify_and_tree (right, &left, insn_code, insn_index);
1858: if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1859: left = simplify_and_tree (left, &right, insn_code, insn_index);
1860:
1861: if (left == false_rtx || right == false_rtx)
1862: return false_rtx;
1863: else if (left == true_rtx)
1864: return right;
1865: else if (right == true_rtx)
1866: return left;
1867:
1868: /* See if all or all but one of the insn's alternatives are specified
1869: in this tree. Optimize if so. */
1870:
1871: else if (insn_code >= 0
1872: && (GET_CODE (left) == AND
1873: || (GET_CODE (left) == NOT
1874: && GET_CODE (XEXP (left, 0)) == EQ_ATTR
1875: && XSTR (XEXP (left, 0), 0) == alternative_name)
1876: || GET_CODE (right) == AND
1877: || (GET_CODE (right) == NOT
1878: && GET_CODE (XEXP (right, 0)) == EQ_ATTR
1879: && XSTR (XEXP (right, 0), 0) == alternative_name)))
1880: {
1881: i = compute_alternative_mask (exp, AND);
1882: if (i & ~insn_alternatives[insn_code])
1883: fatal ("Illegal alternative specified for pattern number %d",
1884: insn_index);
1885:
1886: /* If all alternatives are excluded, this is false. */
1887: i ^= insn_alternatives[insn_code];
1888: if (i == 0)
1889: return false_rtx;
1890: else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1891: {
1892: /* If just one excluded, AND a comparison with that one to the
1893: front of the tree. The others will be eliminated by
1894: optimization. We do not want to do this if the insn has one
1895: alternative and we have tested none of them! */
1896: left = make_alternative_compare (i);
1897: right = simplify_and_tree (exp, &left, insn_code, insn_index);
1898: newexp = rtx_alloc (AND);
1899: XEXP (newexp, 0) = left;
1900: XEXP (newexp, 1) = right;
1901:
1902: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1903: }
1904: }
1905:
1906: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1907: {
1908: newexp = rtx_alloc (AND);
1909: XEXP (newexp, 0) = left;
1910: XEXP (newexp, 1) = right;
1911: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1912: }
1913: break;
1914:
1915: case IOR:
1916: left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1917: right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1918:
1919: right = simplify_or_tree (right, &left, insn_code, insn_index);
1920: if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1921: left = simplify_or_tree (left, &right, insn_code, insn_index);
1922:
1923: if (right == true_rtx || left == true_rtx)
1924: return true_rtx;
1925: else if (left == false_rtx)
1926: return right;
1927: else if (right == false_rtx)
1928: return left;
1929:
1930: /* Test for simple cases where the distributive law is useful. I.e.,
1931: convert (ior (and (x) (y))
1932: (and (x) (z)))
1933: to (and (x)
1934: (ior (y) (z)))
1935: */
1936:
1937: else if (GET_CODE (left) == AND && GET_CODE (right) == AND
1938: && rtx_equal_p (XEXP (left, 0), XEXP (right, 0)))
1939: {
1940: newexp = rtx_alloc (IOR);
1941: XEXP (newexp, 0) = XEXP (left, 1);
1942: XEXP (newexp, 1) = XEXP (right, 1);
1943:
1944: left = XEXP (left, 0);
1945: right = newexp;
1946: newexp = rtx_alloc (AND);
1947: XEXP (newexp, 0) = left;
1948: XEXP (newexp, 1) = right;
1949: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1950: }
1951:
1952: /* See if all or all but one of the insn's alternatives are specified
1953: in this tree. Optimize if so. */
1954:
1955: else if (insn_code >= 0
1956: && (GET_CODE (left) == IOR
1957: || (GET_CODE (left) == EQ_ATTR
1958: && XSTR (left, 0) == alternative_name)
1959: || GET_CODE (right) == IOR
1960: || (GET_CODE (right) == EQ_ATTR
1961: && XSTR (right, 0) == alternative_name)))
1962: {
1963: i = compute_alternative_mask (exp, IOR);
1964: if (i & ~insn_alternatives[insn_code])
1965: fatal ("Illegal alternative specified for pattern number %d",
1966: insn_index);
1967:
1968: /* If all alternatives are included, this is true. */
1969: i ^= insn_alternatives[insn_code];
1970: if (i == 0)
1971: return true_rtx;
1972: else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1973: {
1974: /* If just one excluded, IOR a comparison with that one to the
1975: front of the tree. The others will be eliminated by
1976: optimization. We do not want to do this if the insn has one
1977: alternative and we have tested none of them! */
1978: left = make_alternative_compare (i);
1979: right = simplify_and_tree (exp, &left, insn_code, insn_index);
1980: newexp = rtx_alloc (IOR);
1981: XEXP (newexp, 0) = rtx_alloc (NOT);
1982: XEXP (XEXP (newexp, 0), 0) = left;
1983: XEXP (newexp, 1) = right;
1984:
1985: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1986: }
1987: }
1988:
1989: if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1990: {
1991: newexp = rtx_alloc (IOR);
1992: XEXP (newexp, 0) = left;
1993: XEXP (newexp, 1) = right;
1994: return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1995: }
1996: break;
1997:
1998: case NOT:
1999: left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2000: if (GET_CODE (left) == NOT)
2001: return XEXP (left, 0);
2002:
2003: if (left == false_rtx)
2004: return true_rtx;
2005: else if (left == true_rtx)
2006: return false_rtx;
2007:
2008: /* Try to apply De`Morgan's laws. */
2009: else if (GET_CODE (left) == IOR)
2010: {
2011: newexp = rtx_alloc (AND);
2012: XEXP (newexp, 0) = rtx_alloc (NOT);
2013: XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
2014: XEXP (newexp, 1) = rtx_alloc (NOT);
2015: XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
2016:
2017: newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2018: }
2019: else if (GET_CODE (left) == AND)
2020: {
2021: newexp = rtx_alloc (IOR);
2022: XEXP (newexp, 0) = rtx_alloc (NOT);
2023: XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
2024: XEXP (newexp, 1) = rtx_alloc (NOT);
2025: XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
2026:
2027: newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2028: }
2029: else if (left != XEXP (exp, 0))
2030: {
2031: newexp = rtx_alloc (NOT);
2032: XEXP (newexp, 0) = left;
2033: }
2034: break;
2035:
2036: case EQ_ATTR:
2037: /* Look at the value for this insn code in the specified attribute.
2038: We normally can replace this comparison with the condition that
2039: would give this insn the values being tested for. */
2040: if (XSTR (exp, 0) != alternative_name
2041: && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
2042: for (av = attr->first_value; av; av = av->next)
2043: for (ie = av->first_insn; ie; ie = ie->next)
2044: if (ie->insn_code == insn_code)
2045: return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2046: }
2047:
2048: /* We have already simplified this expression. Simplifying it again
2049: won't buy anything unless we weren't given a valid insn code
2050: to process (i.e., we are canonicalizing something.). */
2051: if (insn_code != -2)
2052: RTX_UNCHANGING_P (newexp) = 1;
2053:
2054: return newexp;
2055: }
2056:
2057: /* Optimize the attribute lists by seeing if we can determine conditional
2058: values from the known values of other attributes. This will save subroutine
2059: calls during the compilation. */
2060:
2061: static void
2062: optimize_attrs ()
2063: {
2064: struct attr_desc *attr;
2065: struct attr_value *av;
2066: struct insn_ent *ie, *nextie;
2067: rtx newexp;
2068: int something_changed = 1;
2069:
2070: /* Loop until nothing changes for one iteration. */
2071: while (something_changed)
2072: {
2073: something_changed = 0;
2074: for (attr = attrs; attr; attr = attr->next)
2075: for (av = attr->first_value; av; av = av->next)
2076: for (ie = av->first_insn; ie; ie = nextie)
2077: {
2078: nextie = ie->next;
2079: if (GET_CODE (av->value) != COND)
2080: continue;
2081:
2082: newexp = simplify_cond (av->value, ie->insn_code,
2083: ie->insn_index);
2084: if (newexp != av->value)
2085: {
2086: remove_insn_ent (av, ie);
2087: insert_insn_ent (get_attr_value (newexp, attr,
2088: ie->insn_code), ie);
2089: something_changed = 1;
2090: }
2091: }
2092: }
2093: }
2094:
2095: /* Create table entries for DEFINE_ATTR. */
2096:
2097: static void
2098: gen_attr (exp)
2099: rtx exp;
2100: {
2101: struct attr_desc *attr;
2102: struct attr_value *av;
2103: char *name_ptr;
2104: char *p;
2105:
2106: /* Make a new attribute structure. Check for duplicate by looking at
2107: attr->default_val, since it is initialized by this routine. */
2108: attr = find_attr (XSTR (exp, 0), 1);
2109: if (attr->default_val)
2110: fatal ("Duplicate definition for `%s' attribute", attr->name);
2111:
2112: if (*XSTR (exp, 1) == '\0')
2113: attr->is_numeric = 1;
2114: else
2115: {
2116: name_ptr = XSTR (exp, 1);
2117: while ((p = next_comma_elt (&name_ptr)) != NULL)
2118: {
2119: av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
2120: av->value = rtx_alloc (CONST_STRING);
2121: XSTR (av->value, 0) = p;
2122: av->next = attr->first_value;
2123: attr->first_value = av;
2124: av->first_insn = NULL;
2125: av->num_insns = 0;
2126: av->has_asm_insn = 0;
2127: }
2128: }
2129:
2130: if (! strcmp (attr->name, "length") && ! attr->is_numeric)
2131: fatal ("`length' attribute must take numeric values");
2132:
2133: /* Set up the default value. */
2134: check_attr_value (XEXP (exp, 2), attr);
2135: attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2136: }
2137:
2138: /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2139: alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2140: number of alternatives as this should be checked elsewhere. */
2141:
2142: static int
2143: count_alternatives (exp)
2144: rtx exp;
2145: {
2146: int i, j, n;
2147: char *fmt;
2148:
2149: if (GET_CODE (exp) == MATCH_OPERAND)
2150: return n_comma_elts (XSTR (exp, 2));
2151:
2152: for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2153: i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2154: switch (*fmt++)
2155: {
2156: case 'e':
2157: case 'u':
2158: n = count_alternatives (XEXP (exp, i));
2159: if (n)
2160: return n;
2161: break;
2162:
2163: case 'E':
2164: case 'V':
2165: if (XVEC (exp, i) != NULL)
2166: for (j = 0; j < XVECLEN (exp, i); j++)
2167: {
2168: n = count_alternatives (XVECEXP (exp, i, j));
2169: if (n)
2170: return n;
2171: }
2172: }
2173:
2174: return 0;
2175: }
2176:
2177: /* Returns non-zero if the given expression contains an EQ_ATTR with the
2178: `alternative' attribute. */
2179:
2180: static int
2181: compares_alternatives_p (exp)
2182: rtx exp;
2183: {
2184: int i, j;
2185: char *fmt;
2186:
2187: if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
2188: return 1;
2189:
2190: for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2191: i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2192: switch (*fmt++)
2193: {
2194: case 'e':
2195: case 'u':
2196: if (compares_alternatives_p (XEXP (exp, i)))
2197: return 1;
2198: break;
2199:
2200: case 'E':
2201: for (j = 0; j < XVECLEN (exp, i); j++)
2202: if (compares_alternatives_p (XVECEXP (exp, i, j)))
2203: return 1;
2204: break;
2205: }
2206:
2207: return 0;
2208: }
2209:
2210: /* Returns non-zero is INNER is contained in EXP. */
2211:
2212: static int
2213: contained_in_p (inner, exp)
2214: rtx inner;
2215: rtx exp;
2216: {
2217: int i, j;
2218: char *fmt;
2219:
2220: if (rtx_equal_p (inner, exp))
2221: return 1;
2222:
2223: for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2224: i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2225: switch (*fmt++)
2226: {
2227: case 'e':
2228: case 'u':
2229: if (contained_in_p (inner, XEXP (exp, i)))
2230: return 1;
2231: break;
2232:
2233: case 'E':
2234: for (j = 0; j < XVECLEN (exp, i); j++)
2235: if (contained_in_p (inner, XVECEXP (exp, i, j)))
2236: return 1;
2237: break;
2238: }
2239:
2240: return 0;
2241: }
2242:
2243: /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2244:
2245: static void
2246: gen_insn (exp)
2247: rtx exp;
2248: {
2249: struct insn_def *id;
2250:
2251: id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
2252: id->next = defs;
2253: defs = id;
2254: id->def = exp;
2255:
2256: switch (GET_CODE (exp))
2257: {
2258: case DEFINE_INSN:
2259: id->insn_code = insn_code_number++;
2260: id->insn_index = insn_index_number++;
2261: id->num_alternatives = count_alternatives (exp);
2262: if (id->num_alternatives == 0)
2263: id->num_alternatives = 1;
2264: id->vec_idx = 4;
2265: break;
2266:
2267: case DEFINE_PEEPHOLE:
2268: id->insn_code = insn_code_number++;
2269: id->insn_index = insn_index_number++;
2270: id->num_alternatives = count_alternatives (exp);
2271: if (id->num_alternatives == 0)
2272: id->num_alternatives = 1;
2273: id->vec_idx = 3;
2274: break;
2275:
2276: case DEFINE_ASM_ATTRIBUTES:
2277: id->insn_code = -1;
2278: id->insn_index = -1;
2279: id->num_alternatives = 1;
2280: id->vec_idx = 0;
2281: got_define_asm_attributes = 1;
2282: break;
2283: }
2284: }
2285:
2286: /* Process a DEFINE_DELAY. Validate the vector length, check if annul
2287: true or annul false is specified, and make a `struct delay_desc'. */
2288:
2289: static void
2290: gen_delay (def)
2291: rtx def;
2292: {
2293: struct delay_desc *delay;
2294: int i;
2295:
2296: if (XVECLEN (def, 1) % 3 != 0)
2297: fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2298:
2299: for (i = 0; i < XVECLEN (def, 1); i += 3)
2300: {
2301: if (XVECEXP (def, 1, i + 1))
2302: have_annul_true = 1;
2303: if (XVECEXP (def, 1, i + 2))
2304: have_annul_false = 1;
2305: }
2306:
2307: delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
2308: delay->def = def;
2309: delay->num = ++num_delays;
2310: delay->next = delays;
2311: delays = delay;
2312: }
2313:
2314: /* Process a DEFINE_FUNCTION_UNIT.
2315:
2316: This gives information about a function unit contained in the CPU.
2317: We fill in a `struct function_unit_op' and a `struct function_unit'
2318: with information used later by `expand_unit'. */
2319:
2320: static void
2321: gen_unit (def)
2322: rtx def;
2323: {
2324: struct function_unit *unit;
2325: struct function_unit_op *op;
2326:
2327: /* See if we have already seen this function unit. If so, check that
2328: the multipicity and simultaneity values are the same. If not, make
2329: a structure for this function unit. */
2330: for (unit = units; unit; unit = unit->next)
2331: if (! strcmp (unit->name, XSTR (def, 0)))
2332: {
2333: if (unit->multiplicity != XINT (def, 1)
2334: || unit->simultaneity != XINT (def, 2))
2335: fatal ("Differing specifications given for `%s' function unit.",
2336: unit->name);
2337: break;
2338: }
2339:
2340: if (unit == 0)
2341: {
2342: unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
2343: unit->name = XSTR (def, 0);
2344: unit->multiplicity = XINT (def, 1);
2345: unit->simultaneity = XINT (def, 2);
2346: unit->num = num_units++;
2347: unit->num_opclasses = 0;
2348: unit->condexp = false_rtx;
2349: unit->ops = 0;
2350: unit->next = units;
2351: units = unit;
2352: }
2353:
2354: /* Make a new operation class structure entry and initialize it. */
2355: op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
2356: op->condexp = XEXP (def, 3);
2357: op->num = unit->num_opclasses++;
2358: op->ready = XINT (def, 4);
2359: op->next = unit->ops;
2360: unit->ops = op;
2361:
2362: /* Set our busy expression based on whether or not an optional conflict
2363: vector was specified. */
2364: if (XVEC (def, 6))
2365: {
2366: /* Compute the IOR of all the specified expressions. */
2367: rtx orexp = false_rtx;
2368: int i;
2369:
2370: for (i = 0; i < XVECLEN (def, 6); i++)
2371: orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
2372:
2373: op->busyexp = rtx_alloc (IF_THEN_ELSE);
2374: XEXP (op->busyexp, 0) = orexp;
2375: XEXP (op->busyexp, 1) = make_numeric_value (XINT (def, 5));
2376: XEXP (op->busyexp, 2) = make_numeric_value (0);
2377: }
2378: else
2379: op->busyexp = make_numeric_value (XINT (def, 5));
2380:
2381: /* Merge our conditional into that of the function unit so we can determine
2382: which insns are used by the function unit. */
2383: unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
2384: }
2385:
2386: /* Given a piece of RTX, print a C expression to test it's truth value.
2387: We use AND and IOR both for logical and bit-wise operations, so
2388: interpret them as logical unless they are inside a comparison expression.
2389: The second operand of this function will be non-zero in that case. */
2390:
2391: static void
2392: write_test_expr (exp, in_comparison)
2393: rtx exp;
2394: int in_comparison;
2395: {
2396: int comparison_operator = 0;
2397: RTX_CODE code;
2398: struct attr_desc *attr;
2399:
2400: /* In order not to worry about operator precedence, surround our part of
2401: the expression with parentheses. */
2402:
2403: printf ("(");
2404: code = GET_CODE (exp);
2405: switch (code)
2406: {
2407: /* Binary operators. */
2408: case EQ: case NE:
2409: case GE: case GT: case GEU: case GTU:
2410: case LE: case LT: case LEU: case LTU:
2411: comparison_operator = 1;
2412:
2413: case PLUS: case MINUS: case MULT: case DIV: case MOD:
2414: case AND: case IOR: case XOR:
2415: case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
2416: write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
2417: switch (code)
2418: {
2419: case EQ:
2420: printf (" == ");
2421: break;
2422: case NE:
2423: printf (" != ");
2424: break;
2425: case GE:
2426: printf (" >= ");
2427: break;
2428: case GT:
2429: printf (" > ");
2430: break;
2431: case GEU:
2432: printf (" >= (unsigned) ");
2433: break;
2434: case GTU:
2435: printf (" > (unsigned) ");
2436: break;
2437: case LE:
2438: printf (" <= ");
2439: break;
2440: case LT:
2441: printf (" < ");
2442: break;
2443: case LEU:
2444: printf (" <= (unsigned) ");
2445: break;
2446: case LTU:
2447: printf (" < (unsigned) ");
2448: break;
2449: case PLUS:
2450: printf (" + ");
2451: break;
2452: case MINUS:
2453: printf (" - ");
2454: break;
2455: case MULT:
2456: printf (" * ");
2457: break;
2458: case DIV:
2459: printf (" / ");
2460: break;
2461: case MOD:
2462: printf (" % ");
2463: break;
2464: case AND:
2465: if (in_comparison)
2466: printf (" & ");
2467: else
2468: printf (" && ");
2469: break;
2470: case IOR:
2471: if (in_comparison)
2472: printf (" | ");
2473: else
2474: printf (" || ");
2475: break;
2476: case XOR:
2477: printf (" ^ ");
2478: break;
2479: case LSHIFT:
2480: case ASHIFT:
2481: printf (" << ");
2482: break;
2483: case LSHIFTRT:
2484: case ASHIFTRT:
2485: printf (" >> ");
2486: break;
2487: }
2488:
2489: write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
2490: break;
2491:
2492: case NOT:
2493: /* Special-case (not (eq_attrq "alternative" "x")) */
2494: if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2495: && XSTR (XEXP (exp, 0), 0) == alternative_name)
2496: {
2497: printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
2498: break;
2499: }
2500:
2501: /* Otherwise, fall through to normal unary operator. */
2502:
2503: /* Unary operators. */
2504: case ABS: case NEG:
2505: switch (code)
2506: {
2507: case NOT:
2508: if (in_comparison)
2509: printf ("~ ");
2510: else
2511: printf ("! ");
2512: break;
2513: case ABS:
2514: printf ("abs ");
2515: break;
2516: case NEG:
2517: printf ("-");
2518: break;
2519: }
2520:
2521: write_test_expr (XEXP (exp, 0), in_comparison);
2522: break;
2523:
2524: /* Comparison test of an attribute with a value. Most of these will
2525: have been removed by optimization. Handle "alternative"
2526: specially and give error if EQ_ATTR present inside a comparison. */
2527: case EQ_ATTR:
2528: if (in_comparison)
2529: fatal ("EQ_ATTR not valid inside comparison");
2530:
2531: if (XSTR (exp, 0) == alternative_name)
2532: {
2533: printf ("which_alternative == %s", XSTR (exp, 1));
2534: break;
2535: }
2536:
2537: attr = find_attr (XSTR (exp, 0), 0);
2538: if (! attr) abort ();
2539: printf ("get_attr_%s (insn) == ", attr->name);
2540: write_attr_valueq (attr, XSTR (exp, 1));
2541: break;
2542:
2543: /* See if an operand matches a predicate. */
2544: case MATCH_OPERAND:
2545: /* If only a mode is given, just ensure the mode matches the operand.
2546: If neither a mode nor predicate is given, error. */
2547: if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
2548: {
2549: if (GET_MODE (exp) == VOIDmode)
2550: fatal ("Null MATCH_OPERAND specified as test");
2551: else
2552: printf ("GET_MODE (operands[%d]) == %smode",
2553: XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2554: }
2555: else
2556: printf ("%s (operands[%d], %smode)",
2557: XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2558: break;
2559:
2560: /* Constant integer. */
2561: case CONST_INT:
2562: printf ("%d", XINT (exp, 0));
2563: break;
2564:
2565: /* A random C expression. */
2566: case SYMBOL_REF:
2567: printf ("%s", XSTR (exp, 0));
2568: break;
2569:
2570: /* The address of the branch target. */
2571: case MATCH_DUP:
2572: printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
2573: break;
2574:
2575: /* The address of the current insn. It would be more consistent with
2576: other usage to make this the address of the NEXT insn, but this gets
2577: too confusing because of the ambiguity regarding the length of the
2578: current insn. */
2579: case PC:
2580: printf ("insn_current_address");
2581: break;
2582:
2583: default:
2584: fatal ("bad RTX code `%s' in attribute calculation\n",
2585: GET_RTX_NAME (code));
2586: }
2587:
2588: printf (")");
2589: }
2590:
2591: /* Given an attribute value, return the maximum CONST_STRING argument
2592: encountered. It is assumed that they are all numeric. */
2593:
2594: static int
2595: max_attr_value (exp)
2596: rtx exp;
2597: {
2598: int current_max = 0;
2599: int n;
2600: int i;
2601:
2602: if (GET_CODE (exp) == CONST_STRING)
2603: return atoi (XSTR (exp, 0));
2604:
2605: else if (GET_CODE (exp) == COND)
2606: {
2607: for (i = 0; i < XVECLEN (exp, 0); i += 2)
2608: {
2609: n = max_attr_value (XVECEXP (exp, 0, i + 1));
2610: if (n > current_max)
2611: current_max = n;
2612: }
2613:
2614: n = max_attr_value (XEXP (exp, 1));
2615: if (n > current_max)
2616: current_max = n;
2617: }
2618:
2619: else
2620: abort ();
2621:
2622: return current_max;
2623: }
2624:
2625: /* Scan an attribute value, possibly a conditional, and record what actions
2626: will be required to do any conditional tests in it.
2627:
2628: Specifically, set
2629: `must_extract' if we need to extract the insn operands
2630: `must_constrain' if we must compute `which_alternative'
2631: `address_used' if an address expression was used
2632: */
2633:
2634: static void
2635: walk_attr_value (exp)
2636: rtx exp;
2637: {
2638: register int i, j;
2639: register char *fmt;
2640: RTX_CODE code;
2641:
2642: if (exp == NULL)
2643: return;
2644:
2645: code = GET_CODE (exp);
2646: switch (code)
2647: {
2648: case SYMBOL_REF:
2649: /* Since this is an arbitrary expression, it can look at anything. */
2650: must_extract = must_constrain = 1;
2651: return;
2652:
2653: case MATCH_OPERAND:
2654: must_extract = 1;
2655: return;
2656:
2657: case EQ_ATTR:
2658: if (XSTR (exp, 0) == alternative_name)
2659: must_extract = must_constrain = 1;
2660: return;
2661:
2662: case MATCH_DUP:
2663: case PC:
2664: address_used = 1;
2665: return;
2666: }
2667:
2668: for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
2669: switch (*fmt++)
2670: {
2671: case 'e':
2672: case 'u':
2673: walk_attr_value (XEXP (exp, i));
2674: break;
2675:
2676: case 'E':
2677: if (XVEC (exp, i) != NULL)
2678: for (j = 0; j < XVECLEN (exp, i); j++)
2679: walk_attr_value (XVECEXP (exp, i, j));
2680: break;
2681: }
2682: }
2683:
2684: /* Write out a function to obtain the attribute for a given INSN. */
2685:
2686: static void
2687: write_attr_get (attr)
2688: struct attr_desc *attr;
2689: {
2690: struct attr_value *av, *common_av;
2691:
2692: /* Find the most used attribute value. Handle that as the `default' of the
2693: switch we will generate. */
2694: common_av = find_most_used (attr);
2695:
2696: /* Write out start of function, then all values with explicit `case' lines,
2697: then a `default', then the value with the most uses. */
2698: if (attr->is_numeric)
2699: printf ("int\n");
2700: else
2701: printf ("enum attr_%s\n", attr->name);
2702:
2703: /* If the attribute name starts with a star, the remainder is the name of
2704: the subroutine to use, instead of `get_attr_...'. */
2705: if (attr->name[0] == '*')
2706: printf ("%s (insn)\n", &attr->name[1]);
2707: else
2708: printf ("get_attr_%s (insn)\n", attr->name);
2709: printf (" rtx insn;\n");
2710: printf ("{\n");
2711: printf (" switch (recog_memoized (insn))\n");
2712: printf (" {\n");
2713:
2714: for (av = attr->first_value; av; av = av->next)
2715: if (av != common_av)
2716: write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
2717:
2718: write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
2719: printf (" }\n}\n\n");
2720: }
2721:
2722: /* Given an AND tree of known true terms (because we are inside an `if' with
2723: that as the condition or are in an `else' clause) and an expression,
2724: replace any known true terms with TRUE. Use `simplify_and_tree' to do
2725: the bulk of the work. */
2726:
2727: static rtx
2728: eliminate_known_true (known_true, exp, insn_code, insn_index)
2729: rtx known_true;
2730: rtx exp;
2731: int insn_code, insn_index;
2732: {
2733: rtx term;
2734:
2735: known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
2736:
2737: if (GET_CODE (known_true) == AND)
2738: {
2739: exp = eliminate_known_true (XEXP (known_true, 0), exp,
2740: insn_code, insn_index);
2741: exp = eliminate_known_true (XEXP (known_true, 1), exp,
2742: insn_code, insn_index);
2743: }
2744: else
2745: {
2746: term = known_true;
2747: exp = simplify_and_tree (exp, &term, insn_code, insn_index);
2748: }
2749:
2750: return exp;
2751: }
2752:
2753: /* Write out a series of tests and assignment statements to perform tests and
2754: sets of an attribute value. We are passed an indentation amount and prefix
2755: and suffix strings to write around each attribute value (e.g., "return"
2756: and ";"). */
2757:
2758: static void
2759: write_attr_set (attr, indent, value, prefix, suffix, known_true,
2760: insn_code, insn_index)
2761: struct attr_desc *attr;
2762: int indent;
2763: rtx value;
2764: char *prefix;
2765: char *suffix;
2766: rtx known_true;
2767: int insn_code, insn_index;
2768: {
2769: if (GET_CODE (value) == CONST_STRING)
2770: {
2771: write_indent (indent);
2772: printf ("%s ", prefix);
2773: write_attr_value (attr, value);
2774: printf ("%s\n", suffix);
2775: }
2776: else if (GET_CODE (value) == COND)
2777: {
2778: /* Assume the default value will be the default of the COND unless we
2779: find an always true expression. */
2780: rtx default_val = XEXP (value, 1);
2781: rtx our_known_true = known_true;
2782: rtx newexp;
2783: int first_if = 1;
2784: int i;
2785:
2786: for (i = 0; i < XVECLEN (value, 0); i += 2)
2787: {
2788: rtx testexp;
2789: rtx inner_true;
2790:
2791: testexp = eliminate_known_true (our_known_true,
2792: XVECEXP (value, 0, i),
2793: insn_code, insn_index);
2794: newexp = rtx_alloc (NOT);
2795: XEXP (newexp, 0) = testexp;
2796: newexp = insert_right_side (AND, our_known_true, newexp,
2797: insn_code, insn_index);
2798:
2799: /* If the test expression is always true or if the next `known_true'
2800: expression is always false, this is the last case, so break
2801: out and let this value be the `else' case. */
2802: if (testexp == true_rtx || newexp == false_rtx)
2803: {
2804: default_val = XVECEXP (value, 0, i + 1);
2805: break;
2806: }
2807:
2808: /* Compute the expression to pass to our recursive call as being
2809: known true. */
2810: inner_true = insert_right_side (AND, our_known_true,
2811: testexp, insn_code, insn_index);
2812:
2813: /* If this is always false, skip it. */
2814: if (inner_true == false_rtx)
2815: continue;
2816:
2817: write_indent (indent);
2818: printf ("%sif ", first_if ? "" : "else ");
2819: first_if = 0;
2820: write_test_expr (testexp, 0);
2821: printf ("\n");
2822: write_indent (indent + 2);
2823: printf ("{\n");
2824:
2825: write_attr_set (attr, indent + 4,
2826: XVECEXP (value, 0, i + 1), prefix, suffix,
2827: inner_true, insn_code, insn_index);
2828: write_indent (indent + 2);
2829: printf ("}\n");
2830: our_known_true = newexp;
2831: }
2832:
2833: if (! first_if)
2834: {
2835: write_indent (indent);
2836: printf ("else\n");
2837: write_indent (indent + 2);
2838: printf ("{\n");
2839: }
2840:
2841: write_attr_set (attr, first_if ? indent : indent + 4, default_val,
2842: prefix, suffix, our_known_true, insn_code, insn_index);
2843:
2844: if (! first_if)
2845: {
2846: write_indent (indent + 2);
2847: printf ("}\n");
2848: }
2849: }
2850: else
2851: abort ();
2852: }
2853:
2854: /* Write out the computation for one attribute value. */
2855:
2856: static void
2857: write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
2858: struct attr_desc *attr;
2859: struct attr_value *av;
2860: int write_case_lines;
2861: char *prefix, *suffix;
2862: int indent;
2863: rtx known_true;
2864: {
2865: struct insn_ent *ie;
2866:
2867: if (av->num_insns == 0)
2868: return;
2869:
2870: if (av->has_asm_insn)
2871: {
2872: write_indent (indent);
2873: printf ("case -1:\n");
2874: write_indent (indent + 2);
2875: printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
2876: write_indent (indent + 2);
2877: printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
2878: write_indent (indent + 2);
2879: printf (" fatal_insn_not_found (insn);\n");
2880: }
2881:
2882: if (write_case_lines)
2883: {
2884: for (ie = av->first_insn; ie; ie = ie->next)
2885: if (ie->insn_code != -1)
2886: {
2887: write_indent (indent);
2888: printf ("case %d:\n", ie->insn_code);
2889: }
2890: }
2891: else
2892: {
2893: write_indent (indent);
2894: printf ("default:\n");
2895: }
2896:
2897: /* See what we have to do to handle output this value. */
2898: must_extract = must_constrain = address_used = 0;
2899: walk_attr_value (av->value);
2900:
2901: if (must_extract)
2902: {
2903: write_indent (indent + 2);
2904: printf ("insn_extract (insn);\n");
2905: }
2906:
2907: if (must_constrain)
2908: {
2909: #ifdef REGISTER_CONSTRAINTS
2910: write_indent (indent + 2);
2911: printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
2912: write_indent (indent + 2);
2913: printf (" fatal_insn_not_found (insn);\n");
2914: #endif
2915: }
2916:
2917: write_attr_set (attr, indent + 2, av->value, prefix, suffix,
2918: known_true, av->first_insn->insn_code,
2919: av->first_insn->insn_index);
2920:
2921: if (strncmp (prefix, "return", 6))
2922: {
2923: write_indent (indent + 2);
2924: printf ("break;\n");
2925: }
2926: printf ("\n");
2927: }
2928:
2929: /* Utilities to write names in various forms. */
2930:
2931: static void
2932: write_attr_valueq (attr, s)
2933: struct attr_desc *attr;
2934: char *s;
2935: {
2936: if (attr->is_numeric)
2937: printf ("%s", s);
2938: else
2939: {
2940: write_upcase (attr->name);
2941: printf ("_");
2942: write_upcase (s);
2943: }
2944: }
2945:
2946: static void
2947: write_attr_value (attr, value)
2948: struct attr_desc *attr;
2949: rtx value;
2950: {
2951: if (GET_CODE (value) != CONST_STRING)
2952: abort ();
2953:
2954: write_attr_valueq (attr, XSTR (value, 0));
2955: }
2956:
2957: static void
2958: write_upcase (str)
2959: char *str;
2960: {
2961: while (*str)
2962: if (*str < 'a' || *str > 'z')
2963: printf ("%c", *str++);
2964: else
2965: printf ("%c", *str++ - 'a' + 'A');
2966: }
2967:
2968: static void
2969: write_indent (indent)
2970: int indent;
2971: {
2972: for (; indent > 8; indent -= 8)
2973: printf ("\t");
2974:
2975: for (; indent; indent--)
2976: printf (" ");
2977: }
2978:
2979: /* Write a subroutine that is given an insn that requires a delay slot, a
2980: delay slot ordinal, and a candidate insn. It returns non-zero if the
2981: candidate can be placed in the specified delay slot of the insn.
2982:
2983: We can write as many as three subroutines. `eligible_for_delay'
2984: handles normal delay slots, `eligible_for_annul_true' indicates that
2985: the specified insn can be annulled if the branch is true, and likewise
2986: for `eligible_for_annul_false'.
2987:
2988: KIND is a string distingushing these three cases ("delay", "annul_true",
2989: or "annul_false"). */
2990:
2991: static void
2992: write_eligible_delay (kind)
2993: char *kind;
2994: {
2995: struct delay_desc *delay;
2996: int max_slots;
2997: char str[50];
2998: struct attr_desc *attr;
2999: struct attr_value *av, *common_av;
3000: int i;
3001:
3002: /* Compute the maximum number of delay slots required. We use the delay
3003: ordinal times this number plus one, plus the slot number as an index into
3004: the appropriate predicate to test. */
3005:
3006: for (delay = delays, max_slots = 0; delay; delay = delay->next)
3007: if (XVECLEN (delay->def, 1) / 3 > max_slots)
3008: max_slots = XVECLEN (delay->def, 1) / 3;
3009:
3010: /* Write function prelude. */
3011:
3012: printf ("int\n");
3013: printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
3014: printf (" rtx delay_insn;\n");
3015: printf (" int slot;\n");
3016: printf (" rtx candidate_insn;\n");
3017: printf ("{\n");
3018: printf (" rtx insn;\n");
3019: printf ("\n");
3020: printf (" if (slot >= %d)\n", max_slots);
3021: printf (" abort ();\n");
3022: printf ("\n");
3023:
3024: /* If more than one delay type, find out which type the delay insn is. */
3025:
3026: if (num_delays > 1)
3027: {
3028: sprintf (str, "*delay_type", kind);
3029: attr = find_attr (str, 0);
3030: if (! attr) abort ();
3031: common_av = find_most_used (attr);
3032:
3033: printf (" insn = delay_insn;\n");
3034: printf (" switch (recog_memoized (insn))\n");
3035: printf (" {\n");
3036:
3037: sprintf (str, " * %d;\n break;", max_slots);
3038: for (av = attr->first_value; av; av = av->next)
3039: if (av != common_av)
3040: write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
3041:
3042: write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
3043: printf (" }\n\n");
3044:
3045: /* Ensure matched. Otherwise, shouldn't have been called. */
3046: printf (" if (slot < %d)\n", max_slots);
3047: printf (" abort ();\n\n");
3048: }
3049:
3050: /* If just one type of delay slot, write simple switch. */
3051: if (num_delays == 1 && max_slots == 1)
3052: {
3053: printf (" insn = candidate_insn;\n");
3054: printf (" switch (recog_memoized (insn))\n");
3055: printf (" {\n");
3056:
3057: attr = find_attr ("*delay_1_0", 0);
3058: if (! attr) abort ();
3059: common_av = find_most_used (attr);
3060:
3061: for (av = attr->first_value; av; av = av->next)
3062: if (av != common_av)
3063: write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3064:
3065: write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3066: printf (" }\n");
3067: }
3068:
3069: else
3070: {
3071: /* Write a nested CASE. The first indicates which condition we need to
3072: test, and the inner CASE tests the condition. */
3073: printf (" insn = candidate_insn;\n");
3074: printf (" switch (slot)\n");
3075: printf (" {\n");
3076:
3077: for (delay = delays; delay; delay = delay->next)
3078: for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
3079: {
3080: printf (" case %d:\n",
3081: (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
3082: printf (" switch (recog_memoized (insn))\n");
3083: printf ("\t{\n");
3084:
3085: sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
3086: attr = find_attr (str, 0);
3087: if (! attr) abort ();
3088: common_av = find_most_used (attr);
3089:
3090: for (av = attr->first_value; av; av = av->next)
3091: if (av != common_av)
3092: write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
3093:
3094: write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
3095: printf (" }\n");
3096: }
3097:
3098: printf (" default:\n");
3099: printf (" abort ();\n");
3100: printf (" }\n");
3101: }
3102:
3103: printf ("}\n\n");
3104: }
3105:
3106: /* Write routines to compute conflict cost for function units. Then write a
3107: table describing the available function units. */
3108:
3109: static void
3110: write_function_unit_info ()
3111: {
3112: struct function_unit *unit;
3113: struct attr_desc *case_attr, *attr;
3114: struct attr_value *av, *common_av;
3115: rtx value;
3116: char *str;
3117: int using_case;
3118: int i;
3119:
3120: /* Write out conflict routines for function units. Don't bother writing
3121: one if there is only one busy value. */
3122:
3123: for (unit = units; unit; unit = unit->next)
3124: {
3125: /* See if only one case exists and if there is a constant value for
3126: that case. If so, we don't need a function. */
3127: str = (char *) xmalloc (strlen (unit->name) + 10);
3128: sprintf (str, "*%s_cases", unit->name);
3129: attr = find_attr (str, 0);
3130: if (! attr) abort ();
3131: value = find_single_value (attr);
3132: if (value && GET_CODE (value) == CONST_STRING)
3133: {
3134: sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
3135: attr = find_attr (str, 0);
3136: if (! attr) abort ();
3137: value = find_single_value (attr);
3138: if (value && GET_CODE (value) == CONST_STRING)
3139: {
3140: unit->needs_conflict_function = 0;
3141: unit->default_cost = value;
3142: continue;
3143: }
3144: }
3145:
3146: /* The function first computes the case from the candidate insn. */
3147: unit->needs_conflict_function = 1;
3148: unit->default_cost = make_numeric_value (0);
3149:
3150: printf ("static int\n");
3151: printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3152: unit->name);
3153: printf (" rtx executing_insn;\n");
3154: printf (" rtx candidate_insn;\n");
3155: printf ("{\n");
3156: printf (" rtx insn;\n");
3157: printf (" int casenum;\n\n");
3158: printf (" insn = candidate_insn;\n");
3159: printf (" switch (recog_memoized (insn))\n");
3160: printf (" {\n");
3161:
3162: /* Write the `switch' statement to get the case value. */
3163: sprintf (str, "*%s_cases", unit->name);
3164: case_attr = find_attr (str, 0);
3165: if (! case_attr) abort ();
3166: common_av = find_most_used (case_attr);
3167:
3168: for (av = case_attr->first_value; av; av = av->next)
3169: if (av != common_av)
3170: write_attr_case (case_attr, av, 1,
3171: "casenum =", ";", 4, unit->condexp);
3172:
3173: write_attr_case (case_attr, common_av, 0,
3174: "casenum =", ";", 4, unit->condexp);
3175: printf (" }\n\n");
3176:
3177: /* Now write an outer switch statement on each case. Then write
3178: the tests on the executing function within each. */
3179: printf (" insn = executing_insn;\n");
3180: printf (" switch (casenum)\n");
3181: printf (" {\n");
3182:
3183: for (i = 0; i < unit->num_opclasses; i++)
3184: {
3185: /* Ensure using this case. */
3186: using_case = 0;
3187: for (av = case_attr->first_value; av; av = av->next)
3188: if (av->num_insns
3189: && contained_in_p (make_numeric_value (i), av->value))
3190: using_case = 1;
3191:
3192: if (! using_case)
3193: continue;
3194:
3195: printf (" case %d:\n", i);
3196: sprintf (str, "*%s_case_%d", unit->name, i);
3197: attr = find_attr (str, 0);
3198: if (! attr) abort ();
3199:
3200: /* If single value, just write it. */
3201: value = find_single_value (attr);
3202: if (value)
3203: write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
3204: else
3205: {
3206: common_av = find_most_used (attr);
3207: printf (" switch (recog_memoized (insn))\n");
3208: printf ("\t{\n");
3209:
3210: for (av = attr->first_value; av; av = av->next)
3211: if (av != common_av)
3212: write_attr_case (attr, av, 1,
3213: "return", ";", 8, unit->condexp);
3214:
3215: write_attr_case (attr, common_av, 0,
3216: "return", ";", 8, unit->condexp);
3217: printf (" }\n\n");
3218: }
3219: }
3220:
3221: printf (" }\n}\n\n");
3222: }
3223:
3224: /* Now that all functions have been written, write the table describing
3225: the function units. The name is included for documenation purposes
3226: only. */
3227:
3228: printf ("struct function_unit_desc function_units[] = {\n");
3229:
3230: for (unit = units; unit; unit = unit->next)
3231: {
3232: printf (" {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3233: unit->name, 1 << unit->num, unit->multiplicity,
3234: unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
3235:
3236: if (unit->needs_conflict_function)
3237: printf ("%s_unit_conflict_cost", unit->name);
3238: else
3239: printf ("0");
3240:
3241: printf ("}, \n");
3242: }
3243:
3244: printf ("};\n\n");
3245: }
3246:
3247: /* This page contains miscellaneous utility routines. */
3248:
3249: /* Given a string, return the number of comma-separated elements in it.
3250: Return 0 for the null string. */
3251:
3252: static int
3253: n_comma_elts (s)
3254: char *s;
3255: {
3256: int n;
3257:
3258: if (*s == '\0')
3259: return 0;
3260:
3261: for (n = 1; *s; s++)
3262: if (*s == ',')
3263: n++;
3264:
3265: return n;
3266: }
3267:
3268: /* Given a pointer to a (char *), return a malloc'ed string containing the
3269: next comma-separated element. Advance the pointer to after the string
3270: scanned, or the end-of-string. Return NULL if at end of string. */
3271:
3272: static char *
3273: next_comma_elt (pstr)
3274: char **pstr;
3275: {
3276: char *out_str;
3277: char *p;
3278:
3279: if (**pstr == '\0')
3280: return NULL;
3281:
3282: /* Find end of string to compute length. */
3283: for (p = *pstr; *p != ',' && *p != '\0'; p++)
3284: ;
3285:
3286: out_str = (char *) xmalloc (p - *pstr + 1);
3287: for (p = out_str; **pstr != ',' && **pstr != '\0'; (*pstr)++)
3288: *p++ = **pstr;
3289:
3290: *p++ = '\0';
3291: if (**pstr == ',')
3292: (*pstr)++;
3293:
3294: return out_str;
3295: }
3296:
3297: /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
3298: is non-zero, build a new attribute, if one does not exist. */
3299:
3300: static struct attr_desc *
3301: find_attr (name, create)
3302: char *name;
3303: int create;
3304: {
3305: struct attr_desc *attr;
3306: char *new_name;
3307:
3308: /* Before we resort to using `strcmp', see if the string address matches
3309: anywhere. In most cases, it should have been canonicalized to do so. */
3310: if (name == alternative_name)
3311: return NULL;
3312:
3313: for (attr = attrs; attr; attr = attr->next)
3314: if (name == attr->name)
3315: return attr;
3316:
3317: /* Otherwise, do it the slow way. */
3318: for (attr = attrs; attr; attr = attr->next)
3319: if (! strcmp (name, attr->name))
3320: return attr;
3321:
3322: if (! create)
3323: return NULL;
3324:
3325: new_name = (char *) xmalloc (strlen (name) + 1);
3326: strcpy (new_name, name);
3327:
3328: attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
3329: attr->name = new_name;
3330: attr->first_value = attr->default_val = NULL;
3331: attr->is_numeric = attr->is_special = 0;
3332: attr->next = attrs;
3333: attrs = attr;
3334:
3335: return attr;
3336: }
3337:
3338: /* Create internal attribute with the given default value. */
3339:
3340: static void
3341: make_internal_attr (name, value, special)
3342: char *name;
3343: rtx value;
3344: int special;
3345: {
3346: struct attr_desc *attr;
3347:
3348: attr = find_attr (name, 1);
3349: if (attr->default_val)
3350: abort ();
3351:
3352: attr->is_numeric = 1;
3353: attr->is_special = special;
3354: attr->default_val = get_attr_value (value, attr, -2);
3355: }
3356:
3357: /* Find the most used value of an attribute. */
3358:
3359: static struct attr_value *
3360: find_most_used (attr)
3361: struct attr_desc *attr;
3362: {
3363: struct attr_value *av;
3364: struct attr_value *most_used;
3365: int nuses;
3366:
3367: most_used = NULL;
3368: nuses = -1;
3369:
3370: for (av = attr->first_value; av; av = av->next)
3371: if (av->num_insns > nuses)
3372: nuses = av->num_insns, most_used = av;
3373:
3374: return most_used;
3375: }
3376:
3377: /* If an attribute only has a single value used, return it. Otherwise
3378: return NULL. */
3379:
3380: static rtx
3381: find_single_value (attr)
3382: struct attr_desc *attr;
3383: {
3384: struct attr_value *av;
3385: rtx unique_value;
3386:
3387: unique_value = NULL;
3388: for (av = attr->first_value; av; av = av->next)
3389: if (av->num_insns)
3390: {
3391: if (unique_value)
3392: return NULL;
3393: else
3394: unique_value = av->value;
3395: }
3396:
3397: return unique_value;
3398: }
3399:
3400: /* Return (attr_value "n") */
3401:
3402: static rtx
3403: make_numeric_value (n)
3404: int n;
3405: {
3406: static rtx int_values[20];
3407: rtx exp;
3408:
3409: if (n < 0)
3410: abort ();
3411:
3412: if (n < 20 && int_values[n])
3413: return int_values[n];
3414:
3415: exp = rtx_alloc (CONST_STRING);
3416: XSTR (exp, 0) = (char *) xmalloc ((n < 1000 ? 4
3417: : HOST_BITS_PER_INT * 3 / 10 + 3));
3418: sprintf (XSTR (exp, 0), "%d", n);
3419:
3420: if (n < 20)
3421: int_values[n] = exp;
3422:
3423: return exp;
3424: }
3425:
3426: char *
3427: xrealloc (ptr, size)
3428: char *ptr;
3429: unsigned size;
3430: {
3431: char *result = (char *) realloc (ptr, size);
3432: if (!result)
3433: fatal ("virtual memory exhausted");
3434: return result;
3435: }
3436:
3437: char *
3438: xmalloc (size)
3439: unsigned size;
3440: {
3441: register char *val = (char *) malloc (size);
3442:
3443: if (val == 0)
3444: fatal ("virtual memory exhausted");
3445: return val;
3446: }
3447:
3448: static void
3449: fatal (s, a1, a2)
3450: char *s;
3451: {
3452: fprintf (stderr, "genattrtab: ");
3453: fprintf (stderr, s, a1, a2);
3454: fprintf (stderr, "\n");
3455: exit (FATAL_EXIT_CODE);
3456: }
3457:
3458: /* More 'friendly' abort that prints the line and file.
3459: config.h can #define abort fancy_abort if you like that sort of thing. */
3460:
3461: void
3462: fancy_abort ()
3463: {
3464: fatal ("Internal gcc abort.");
3465: }
3466:
3467: int
3468: main (argc, argv)
3469: int argc;
3470: char **argv;
3471: {
3472: rtx desc;
3473: FILE *infile;
3474: extern rtx read_rtx ();
3475: register int c;
3476: struct attr_desc *attr;
3477: struct attr_value *av;
3478: struct insn_def *id;
3479: rtx tem;
3480:
3481: obstack_init (rtl_obstack);
3482:
3483: if (argc <= 1)
3484: fatal ("No input file name.");
3485:
3486: infile = fopen (argv[1], "r");
3487: if (infile == 0)
3488: {
3489: perror (argv[1]);
3490: exit (FATAL_EXIT_CODE);
3491: }
3492:
3493: init_rtl ();
3494:
3495: /* Set up true and false rtx's */
3496: true_rtx = rtx_alloc (CONST_INT);
3497: false_rtx = rtx_alloc (CONST_INT);
3498: XINT (true_rtx, 0) = 1;
3499: XINT (false_rtx, 0) = 0;
3500: RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
3501:
3502: printf ("/* Generated automatically by the program `genattrtab'\n\
3503: from the machine description file `md'. */\n\n");
3504:
3505: /* Read the machine description. */
3506:
3507: while (1)
3508: {
3509: c = read_skip_spaces (infile);
3510: if (c == EOF)
3511: break;
3512: ungetc (c, infile);
3513:
3514: desc = read_rtx (infile);
3515: if (GET_CODE (desc) == DEFINE_INSN
3516: || GET_CODE (desc) == DEFINE_PEEPHOLE
3517: || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
3518: gen_insn (desc);
3519:
3520: else if (GET_CODE (desc) == DEFINE_EXPAND)
3521: insn_code_number++, insn_index_number++;
3522:
3523: else if (GET_CODE (desc) == DEFINE_SPLIT)
3524: insn_code_number++, insn_index_number++;
3525:
3526: else if (GET_CODE (desc) == DEFINE_ATTR)
3527: {
3528: gen_attr (desc);
3529: insn_index_number++;
3530: }
3531:
3532: else if (GET_CODE (desc) == DEFINE_DELAY)
3533: {
3534: gen_delay (desc);
3535: insn_index_number++;
3536: }
3537:
3538: else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
3539: {
3540: gen_unit (desc);
3541: insn_index_number++;
3542: }
3543: }
3544:
3545: /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
3546: if (! got_define_asm_attributes)
3547: {
3548: tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
3549: XVEC (tem, 0) = rtvec_alloc (0);
3550: gen_insn (tem);
3551: }
3552:
3553: /* Expand DEFINE_DELAY information into new attribute. */
3554: if (num_delays)
3555: expand_delays ();
3556:
3557: /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
3558: if (num_units)
3559: expand_units ();
3560:
3561: printf ("#include \"config.h\"\n");
3562: printf ("#include \"rtl.h\"\n");
3563: printf ("#include \"insn-config.h\"\n");
3564: printf ("#include \"recog.h\"\n");
3565: printf ("#include \"regs.h\"\n");
3566: printf ("#include \"real.h\"\n");
3567: printf ("#include \"output.h\"\n");
3568: printf ("#include \"insn-attr.h\"\n");
3569: printf ("\n");
3570: printf ("#define operands recog_operand\n\n");
3571:
3572: /* Make `insn_alternatives'. */
3573: insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
3574: for (id = defs; id; id = id->next)
3575: if (id->insn_code >= 0)
3576: insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
3577:
3578: /* Prepare to write out attribute subroutines by checking everything stored
3579: away and building the attribute cases. */
3580:
3581: check_defs ();
3582: for (attr = attrs; attr; attr = attr->next)
3583: {
3584: check_attr_value (attr->default_val->value, attr);
3585: fill_attr (attr);
3586: }
3587:
3588: /* Construct extra attributes for `length'. */
3589: make_length_attrs ();
3590:
3591: /* Perform any possible optimizations to speed up compilation. */
3592: optimize_attrs ();
3593:
3594: /* Now write out all the `gen_attr_...' routines. Do these before the
3595: special routines (specifically before write_function_unit_info), so
3596: that they get defined before they are used. */
3597:
3598: for (attr = attrs; attr; attr = attr->next)
3599: {
3600: if (! attr->is_special)
3601: write_attr_get (attr);
3602: }
3603:
3604: /* Write out delay eligibility information, if DEFINE_DELAY present.
3605: (The function to compute the number of delay slots will be written
3606: below.) */
3607: if (num_delays)
3608: {
3609: write_eligible_delay ("delay");
3610: if (have_annul_true)
3611: write_eligible_delay ("annul_true");
3612: if (have_annul_false)
3613: write_eligible_delay ("annul_false");
3614: }
3615:
3616: /* Write out information about function units. */
3617: if (num_units)
3618: write_function_unit_info ();
3619:
3620: fflush (stdout);
3621: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
3622: /* NOTREACHED */
3623: return 0;
3624: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.