]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genattrtab.c
Initial revision
[thirdparty/gcc.git] / gcc / genattrtab.c
CommitLineData
41299f41
TW
1/* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@nyu.edu)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the 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
77static struct obstack obstack;
78struct obstack *rtl_obstack = &obstack;
79
80#define obstack_chunk_alloc xmalloc
81#define obstack_chunk_free free
82
83extern void free ();
84
85static void fatal ();
86void 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
95struct 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
109struct 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
120struct 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
131struct 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
143struct 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
152struct 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
164struct 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
182static struct attr_desc *attrs;
183static struct insn_def *defs;
184static struct delay_desc *delays;
185static struct function_unit *units;
186
187/* Other variables. */
188
189static int insn_code_number;
190static int insn_index_number;
191static int got_define_asm_attributes;
192static int must_extract;
193static int must_constrain;
194static int address_used;
195static int num_delays;
196static int have_annul_true, have_annul_false;
197static int num_units;
198
199/* Used as operand to `operate_exp': */
200
201enum 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
206static int *insn_alternatives;
207
208/* Used to simplify expressions. */
209
210static rtx true_rtx, false_rtx;
211
212/* Used to reduce calls to `strcmp' */
213
214static 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
225rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
226
227static rtx check_attr_test ();
228static void check_attr_value ();
229static rtx convert_set_attr_alternative ();
230static rtx convert_set_attr ();
231static void check_defs ();
232static rtx make_canonical ();
233static struct attr_value *get_attr_value ();
234static void expand_delays ();
235static rtx operate_exp ();
236static void expand_units ();
237static void fill_attr ();
238static rtx substitute_address ();
239static void make_length_attrs ();
240static rtx identity_fn ();
241static rtx zero_fn ();
242static rtx one_fn ();
243static rtx max_fn ();
244static rtx simplify_cond ();
245static void remove_insn_ent ();
246static void insert_insn_ent ();
247static rtx insert_right_side ();
248static rtx make_alternative_compare ();
249static int compute_alternative_mask ();
250static rtx evaluate_eq_attr ();
251static rtx simplify_and_tree ();
252static rtx simplify_or_tree ();
253static rtx simplify_test_exp ();
254static void optimize_attrs ();
255static void gen_attr ();
256static int count_alternatives ();
257static int compares_alternatives_p ();
258static int contained_in_p ();
259static void gen_insn ();
260static void gen_delay ();
261static void gen_unit ();
262static void write_test_expr ();
263static int max_attr_value ();
264static void walk_attr_value ();
265static void write_attr_get ();
266static rtx eliminate_known_true ();
267static void write_attr_set ();
268static void write_attr_case ();
269static void write_attr_value ();
270static void write_attr_valueq ();
271static void write_upcase ();
272static void write_indent ();
273static void write_eligible_delay ();
274static void write_function_unit_info ();
275static int n_comma_elts ();
276static char *next_comma_elt ();
277static struct attr_desc *find_attr ();
278static void make_internal_attr ();
279static struct attr_value *find_most_used ();
280static rtx find_single_value ();
281static rtx make_numeric_value ();
282char *xrealloc ();
283char *xmalloc ();
284static void fatal ();
285\f
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
297static rtx
298check_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\f
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
410static void
411check_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\f
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
484static rtx
485convert_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\f
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
525static rtx
526convert_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\f
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
569static void
570check_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\f
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
624static rtx
625make_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\f
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
684static struct attr_value *
685get_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\f
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
733static void
734expand_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\f
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
828static rtx
829operate_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\f
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
956static void
957expand_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\f
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
1042static void
1043fill_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\f
1075/* Given an expression EXP, see if it is a COND that has a test that checks
1076 relative positions of insns (uses MATCH_DUP or PC). If so, replace it
1077 with what is obtained by passing the expression to ADDRESS_FN. If not
1078 but it is a COND, call this routine recursively on each value (including
1079 the default value). Otherwise, return the value returned by NO_ADDRESS_FN
1080 applied to EXP. */
1081
1082static rtx
1083substitute_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 return (*no_address_fn) (exp);
1093
1094 /* See if any tests use addresses. */
1095 address_used = 0;
1096 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1097 walk_attr_value (XVECEXP (exp, 0, i));
1098
1099 if (address_used)
1100 return (*address_fn) (exp);
1101
1102 /* Make a new copy of this COND, replacing each element. */
1103 newexp = rtx_alloc (COND);
1104 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1105 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1106 {
1107 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1108 XVECEXP (newexp, 0, i + 1) = substitute_address (XVECEXP (exp, 0, i + 1),
1109 no_address_fn,
1110 address_fn);
1111 }
1112
1113 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1114 no_address_fn, address_fn);
1115
1116 return newexp;
1117}
1118\f
1119/* Make new attributes from the `length' attribute. The following are made,
1120 each corresponding to a function called from `shorten_branches' or
1121 `get_attr_length':
1122
1123 *insn_default_length This is the length of the insn to be returned
1124 by `get_attr_length' before `shorten_branches'
1125 has been called. In each case where the length
1126 depends on relative addresses, the largest
1127 possible is used. This routine is also used
1128 to compute the initial size of the insn.
1129
1130 *insn_variable_length_p This returns 1 if the insn's length depends
1131 on relative addresses, zero otherwise.
1132
1133 *insn_current_length This is only called when it is known that the
1134 insn has a variable length and returns the
1135 current length, based on relative addresses.
1136 */
1137
1138static void
1139make_length_attrs ()
1140{
1141 static char *new_names[] = {"*insn_default_length",
1142 "*insn_variable_length_p",
1143 "*insn_current_length"};
1144 static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
1145 static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
1146 int i;
1147 struct attr_desc *length_attr, *new_attr;
1148 struct attr_value *av, *new_av;
1149 struct insn_ent *ie, *new_ie;
1150
1151 /* See if length attribute is defined. If so, it must be numeric. Make
1152 it special so we don't output anything for it. */
1153 length_attr = find_attr ("length", 0);
1154 if (length_attr == 0)
1155 return;
1156
1157 if (! length_attr->is_numeric)
1158 fatal ("length attribute must be numeric.");
1159
1160 length_attr->is_special = 1;
1161
1162 /* Make each new attribute, in turn. */
1163 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
1164 {
1165 make_internal_attr (new_names[i],
1166 substitute_address (length_attr->default_val->value,
1167 no_address_fn[i], address_fn[i]),
1168 0);
1169 new_attr = find_attr (new_names[i], 0);
1170 for (av = length_attr->first_value; av; av = av->next)
1171 for (ie = av->first_insn; ie; ie = ie->next)
1172 {
1173 new_av = get_attr_value (substitute_address (av->value,
1174 no_address_fn[i],
1175 address_fn[i]),
1176 new_attr, ie->insn_code);
1177 new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1178 new_ie->insn_code = ie->insn_code;
1179 new_ie->insn_index = ie->insn_index;
1180 insert_insn_ent (new_av, new_ie);
1181 }
1182 }
1183}
1184
1185/* Utility functions called from above routine. */
1186
1187static rtx
1188identity_fn (exp)
1189 rtx exp;
1190{
1191 return exp;
1192}
1193
1194static rtx
1195zero_fn (exp)
1196 rtx exp;
1197{
1198 return make_numeric_value (0);
1199}
1200
1201static rtx
1202one_fn (exp)
1203 rtx exp;
1204{
1205 return make_numeric_value (1);
1206}
1207
1208static rtx
1209max_fn (exp)
1210 rtx exp;
1211{
1212 return make_numeric_value (max_attr_value (exp));
1213}
1214\f
1215/* Take a COND expression and see if any of the conditions in it can be
1216 simplified. If any are known true or known false for the particular insn
1217 code, the COND can be further simplified.
1218
1219 Also call ourselves on any COND operations that are values of this COND.
1220
1221 We only do the first replacement found directly and call ourselves
1222 recursively for subsequent replacements. */
1223
1224static rtx
1225simplify_cond (exp, insn_code, insn_index)
1226 rtx exp;
1227 int insn_code, insn_index;
1228{
1229 int i, j;
1230 rtx newtest;
1231 rtx value;
1232 rtx newexp = exp;
1233
1234 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1235 {
1236 newtest = SIMPLIFY_TEST_EXP (XVECEXP (exp, 0, i), insn_code, insn_index);
1237 if (newtest == true_rtx)
1238 {
1239 /* Make a new COND with any previous conditions and the value for
1240 this pair as the default value. */
1241 newexp = rtx_alloc (COND);
1242 XVEC (newexp, 0) = rtvec_alloc (i);
1243 for (j = 0; j < i; j++)
1244 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1245
1246 XEXP (newexp, 1) = XVECEXP (exp, 0, i + 1);
1247 break;
1248 }
1249
1250 else if (newtest == false_rtx)
1251 {
1252 /* Build a new COND without this test. */
1253 newexp = rtx_alloc (COND);
1254 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1255 for (j = 0; j < i; j++)
1256 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1257
1258 for (j = i; j < XVECLEN (newexp, 0); j++)
1259 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1260
1261 XEXP (newexp, 1) = XEXP (exp, 1);
1262 break;
1263 }
1264
1265 else if (newtest != XVECEXP (exp, 0, i))
1266 {
1267 newexp = rtx_alloc (COND);
1268 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1269 for (j = 0; j < XVECLEN (exp, 0); j++)
1270 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1271 XEXP (newexp, 1) = XEXP (exp, 1);
1272
1273 XVECEXP (newexp, 0, i) = newtest;
1274 break;
1275 }
1276
1277 /* See if this value may need simplification. */
1278 if (GET_CODE (XVECEXP (exp, 0, i + 1)) == COND)
1279 {
1280 value = simplify_cond (XVECEXP (exp, 0, i + 1),
1281 insn_code, insn_index);
1282 if (value != XVECEXP (exp, 0, i + 1))
1283 {
1284 newexp = rtx_alloc (COND);
1285 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1286 for (j = 0; j < XVECLEN (exp, 0); j++)
1287 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1288 XEXP (newexp, 1) = XEXP (exp, 1);
1289
1290 XVECEXP (newexp, 0, i + 1) = value;
1291 break;
1292 }
1293 }
1294
1295 /* If this is the last condition in a COND and our value is the same
1296 as the default value, our test isn't needed. */
1297 if (i == XVECLEN (exp, 0) - 2
1298 && rtx_equal_p (XVECEXP (exp, 0, i + 1), XEXP (exp, 1)))
1299 {
1300 newexp = rtx_alloc (COND);
1301 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1302 for (j = 0; j < i; j++)
1303 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1304 XEXP (newexp, 1) = XEXP (exp, 1);
1305 break;
1306 }
1307
1308 /* If this value and the value for the next test are the same, merge the
1309 tests. */
1310 else if (i != XVECLEN (exp, 0) - 2
1311 && rtx_equal_p (XVECEXP (exp, 0, i + 1),
1312 XVECEXP (exp, 0, i + 3)))
1313 {
1314 newexp = rtx_alloc (COND);
1315 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1316 for (j = 0; j < i; j++)
1317 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1318
1319 XVECEXP (newexp, 0, j)
1320 = insert_right_side (IOR, XVECEXP (exp, 0, i),
1321 XVECEXP (exp, 0, i + 2),
1322 insn_code, insn_index);
1323 XVECEXP (newexp, 0, j + 1) = XVECEXP (exp, 0, i + 1);
1324
1325 for (j = i + 2; j < XVECLEN (newexp, 0); j++)
1326 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1327
1328 XEXP (newexp, 1) = XEXP (exp, 1);
1329 break;
1330 }
1331 }
1332
1333 /* See if default value needs simplification. */
1334 if (GET_CODE (XEXP (exp, 1)) == COND)
1335 {
1336 value = simplify_cond (XEXP (exp, 1), insn_code, insn_index);
1337 if (value != XEXP (exp, 1))
1338 {
1339 newexp = rtx_alloc (COND);
1340 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1341 for (j = 0; j < XVECLEN (exp, 0); j++)
1342 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1343 XEXP (newexp, 1) = value;
1344 }
1345 }
1346
1347 if (exp == newexp)
1348 return exp;
1349 else if (XVECLEN (newexp, 0) == 1)
1350 return XVECEXP (newexp, 0, 0);
1351 else
1352 return simplify_cond (newexp, insn_code, insn_index);
1353}
1354\f
1355/* Remove an insn entry from an attribute value. */
1356
1357static void
1358remove_insn_ent (av, ie)
1359 struct attr_value *av;
1360 struct insn_ent *ie;
1361{
1362 struct insn_ent *previe;
1363
1364 if (av->first_insn == ie)
1365 av->first_insn = ie->next;
1366 else
1367 {
1368 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1369 ;
1370 previe->next = ie->next;
1371 }
1372
1373 av->num_insns--;
1374 if (ie->insn_code == -1)
1375 av->has_asm_insn = 0;
1376}
1377
1378/* Insert an insn entry in an attribute value list. */
1379
1380static void
1381insert_insn_ent (av, ie)
1382 struct attr_value *av;
1383 struct insn_ent *ie;
1384{
1385 ie->next = av->first_insn;
1386 av->first_insn = ie;
1387 av->num_insns++;
1388 if (ie->insn_code == -1)
1389 av->has_asm_insn = 1;
1390}
1391\f
1392/* This is a utility routine to take an expression that is a tree of either
1393 AND or IOR expressions and insert a new term. The new term will be
1394 inserted at the right side of the first node whose code does not match
1395 the root. A new node will be created with the root's code. Its left
1396 side will be the old right side and its right side will be the new
1397 term.
1398
1399 If the `term' is itself a tree, all its leaves will be inserted. */
1400
1401static rtx
1402insert_right_side (code, exp, term, insn_code, insn_index)
1403 RTX_CODE code;
1404 rtx exp;
1405 rtx term;
1406 int insn_code, insn_index;
1407{
1408 rtx newexp;
1409
1410 if (GET_CODE (term) == code)
1411 {
1412 exp = insert_right_side (code, exp, XEXP (term, 0),
1413 insn_code, insn_index);
1414 exp = insert_right_side (code, exp, XEXP (term, 1),
1415 insn_code, insn_index);
1416
1417 return exp;
1418 }
1419
1420 if (GET_CODE (exp) == code)
1421 {
1422 /* Make a copy of this expression and call recursively. */
1423 newexp = rtx_alloc (code);
1424 XEXP (newexp, 0) = XEXP (exp, 0);
1425 XEXP (newexp, 1) = insert_right_side (code, XEXP (exp, 1),
1426 term, insn_code, insn_index);
1427 }
1428 else
1429 {
1430 /* Insert the new term. */
1431 newexp = rtx_alloc (code);
1432 XEXP (newexp, 0) = exp;
1433 XEXP (newexp, 1) = term;
1434 }
1435
1436 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1437}
1438\f
1439/* If we have an expression which AND's a bunch of
1440 (not (eq_attrq "alternative" "n"))
1441 terms, we may have covered all or all but one of the possible alternatives.
1442 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1443
1444 This routine is passed an expression and either AND or IOR. It returns a
1445 bitmask indicating which alternatives are present. */
1446
1447static int
1448compute_alternative_mask (exp, code)
1449 rtx exp;
1450 RTX_CODE code;
1451{
1452 if (GET_CODE (exp) == code)
1453 return compute_alternative_mask (XEXP (exp, 0), code)
1454 | compute_alternative_mask (XEXP (exp, 1), code);
1455
1456 else if (code == AND && GET_CODE (exp) == NOT
1457 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1458 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1459 return 1 << atoi (XSTR (XEXP (exp, 0), 1));
1460
1461 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1462 && XSTR (exp, 0) == alternative_name)
1463 return 1 << atoi (XSTR (exp, 1));
1464
1465 else
1466 return 0;
1467}
1468
1469/* Given I, a single-bit mask, return RTX to compare the `alternative'
1470 attribute with the value represented by that bit. */
1471
1472static rtx
1473make_alternative_compare (mask)
1474 int mask;
1475{
1476 rtx newexp;
1477 int i;
1478 char *alternative;
1479
1480 /* Find the bit. */
1481 for (i = 0; (mask & (1 << i)) == 0; i++)
1482 ;
1483
1484 alternative = (char *) xmalloc (3);
1485 sprintf (alternative, "%d", i);
1486
1487 newexp = rtx_alloc (EQ_ATTR);
1488 XSTR (newexp, 0) = alternative_name;
1489 XSTR (newexp, 1) = alternative;
1490 RTX_UNCHANGING_P (newexp) = 1;
1491
1492 return newexp;
1493}
1494\f
1495/* If we are processing an (eq_attr "attr" "value") test, we find the value
1496 of "attr" for this insn code. From that value, we can compute a test
1497 showing when the EQ_ATTR will be true. This routine performs that
1498 computation. If a test condition involves an address, we leave the EQ_ATTR
1499 intact because addresses are only valid for the `length' attribute. */
1500
1501static rtx
1502evaluate_eq_attr (exp, value, insn_code, insn_index)
1503 rtx exp;
1504 rtx value;
1505 int insn_code, insn_index;
1506{
1507 rtx orexp, andexp;
1508 rtx right;
1509 rtx newexp;
1510 int i;
1511
1512 if (GET_CODE (value) == CONST_STRING)
1513 {
1514 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
1515 newexp = true_rtx;
1516 else
1517 newexp = false_rtx;
1518 }
1519 else if (GET_CODE (value) == COND)
1520 {
1521 /* We construct an IOR of all the cases for which the requested attribute
1522 value is present. Since we start with FALSE, if it is not present,
1523 FALSE will be returned.
1524
1525 Each case is the AND of the NOT's of the previous conditions with the
1526 current condition; in the default case the current condition is TRUE.
1527
1528 For each possible COND value, call ourselves recursively.
1529
1530 The extra TRUE and FALSE expressions will be eliminated by another
1531 call to the simplification routine. */
1532
1533 orexp = false_rtx;
1534 andexp = true_rtx;
1535
1536 for (i = 0; i < XVECLEN (value, 0); i += 2)
1537 {
1538 right = insert_right_side (AND, andexp,
1539 XVECEXP (value, 0, i),
1540 insn_code, insn_index);
1541 right = insert_right_side (AND, right,
1542 evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
1543 insn_code, insn_index),
1544 insn_code, insn_index);
1545 orexp = insert_right_side (IOR, orexp, right,
1546 insn_code, insn_index);
1547
1548 /* Add this condition into the AND expression. */
1549 newexp = rtx_alloc (NOT);
1550 XEXP (newexp, 0) = XVECEXP (value, 0, i);
1551 andexp = insert_right_side (AND, andexp, newexp,
1552 insn_code, insn_index);
1553 }
1554
1555 /* Handle the default case. */
1556 right = insert_right_side (AND, andexp,
1557 evaluate_eq_attr (exp, XEXP (value, 1),
1558 insn_code, insn_index),
1559 insn_code, insn_index);
1560 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
1561 }
1562 else
1563 abort ();
1564
1565 /* If uses an address, must return original expression. */
1566
1567 address_used = 0;
1568 walk_attr_value (newexp);
1569
1570 if (address_used)
1571 return exp;
1572 else
1573 return newexp;
1574}
1575\f
1576/* This routine is called when an AND of a term with a tree of AND's is
1577 encountered. If the term or its complement is present in the tree, it
1578 can be replaced with TRUE or FALSE, respectively.
1579
1580 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
1581 be true and hence are complementary.
1582
1583 There is one special case: If we see
1584 (and (not (eq_attr "att" "v1"))
1585 (eq_attr "att" "v2"))
1586 this can be replaced by (eq_attr "att" "v2"). To do this we need to
1587 replace the term, not anything in the AND tree. So we pass a pointer to
1588 the term. */
1589
1590static rtx
1591simplify_and_tree (exp, pterm, insn_code, insn_index)
1592 rtx exp;
1593 rtx *pterm;
1594 int insn_code, insn_index;
1595{
1596 rtx left, right;
1597 rtx newexp;
1598 rtx temp;
1599 int left_eliminates_term, right_eliminates_term;
1600
1601 if (GET_CODE (exp) == AND)
1602 {
1603 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1604 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1605 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1606 {
1607 newexp = rtx_alloc (GET_CODE (exp));
1608 XEXP (newexp, 0) = left;
1609 XEXP (newexp, 1) = right;
1610
1611 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1612 }
1613 }
1614
1615 else if (GET_CODE (exp) == IOR)
1616 {
1617 /* For the IOR case, we do the same as above, except that we can
1618 only eliminate `term' if both sides of the IOR would do so. */
1619 temp = *pterm;
1620 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1621 left_eliminates_term = (temp == true_rtx);
1622
1623 temp = *pterm;
1624 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1625 right_eliminates_term = (temp == true_rtx);
1626
1627 if (left_eliminates_term && right_eliminates_term)
1628 *pterm = true_rtx;
1629
1630 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1631 {
1632 newexp = rtx_alloc (GET_CODE (exp));
1633 XEXP (newexp, 0) = left;
1634 XEXP (newexp, 1) = right;
1635
1636 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1637 }
1638 }
1639
1640 /* Check for simplifications. Do some extra checking here since this
1641 routine is called so many times. */
1642
1643 if (exp == *pterm)
1644 return true_rtx;
1645
1646 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
1647 return false_rtx;
1648
1649 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
1650 return false_rtx;
1651
1652 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
1653 {
1654 if (XSTR (exp, 0) != XSTR (*pterm, 0))
1655 return exp;
1656
1657 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
1658 return true_rtx;
1659 else
1660 return false_rtx;
1661 }
1662
1663 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1664 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
1665 {
1666 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
1667 return exp;
1668
1669 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
1670 return false_rtx;
1671 else
1672 return true_rtx;
1673 }
1674
1675 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1676 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
1677 {
1678 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
1679 return exp;
1680
1681 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
1682 return false_rtx;
1683 else
1684 *pterm = true_rtx;
1685 }
1686
1687 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
1688 {
1689 if (rtx_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
1690 return true_rtx;
1691 }
1692
1693 else if (GET_CODE (exp) == NOT)
1694 {
1695 if (rtx_equal_p (XEXP (exp, 0), *pterm))
1696 return false_rtx;
1697 }
1698
1699 else if (GET_CODE (*pterm) == NOT)
1700 {
1701 if (rtx_equal_p (XEXP (*pterm, 0), exp))
1702 return false_rtx;
1703 }
1704
1705 else if (rtx_equal_p (exp, *pterm))
1706 return true_rtx;
1707
1708 return exp;
1709}
1710\f
1711/* Similiar to `simplify_and_tree', but for IOR trees. */
1712
1713static rtx
1714simplify_or_tree (exp, pterm, insn_code, insn_index)
1715 rtx exp;
1716 rtx *pterm;
1717 int insn_code, insn_index;
1718{
1719 rtx left, right;
1720 rtx newexp;
1721 rtx temp;
1722 int left_eliminates_term, right_eliminates_term;
1723
1724 if (GET_CODE (exp) == IOR)
1725 {
1726 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1727 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1728 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1729 {
1730 newexp = rtx_alloc (GET_CODE (exp));
1731 XEXP (newexp, 0) = left;
1732 XEXP (newexp, 1) = right;
1733
1734 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1735 }
1736 }
1737
1738 else if (GET_CODE (exp) == AND)
1739 {
1740 /* For the AND case, we do the same as above, except that we can
1741 only eliminate `term' if both sides of the AND would do so. */
1742 temp = *pterm;
1743 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1744 left_eliminates_term = (temp == false_rtx);
1745
1746 temp = *pterm;
1747 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1748 right_eliminates_term = (temp == false_rtx);
1749
1750 if (left_eliminates_term && right_eliminates_term)
1751 *pterm = false_rtx;
1752
1753 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1754 {
1755 newexp = rtx_alloc (GET_CODE (exp));
1756 XEXP (newexp, 0) = left;
1757 XEXP (newexp, 1) = right;
1758
1759 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1760 }
1761 }
1762
1763 if (rtx_equal_p (exp, *pterm))
1764 return false_rtx;
1765
1766 else if (GET_CODE (exp) == NOT && rtx_equal_p (XEXP (exp, 0), *pterm))
1767 return true_rtx;
1768
1769 else if (GET_CODE (*pterm) == NOT && rtx_equal_p (XEXP (*pterm, 0), exp))
1770 return true_rtx;
1771
1772 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1773 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1774 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
1775 *pterm = false_rtx;
1776
1777 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1778 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
1779 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
1780 return false_rtx;
1781
1782 return exp;
1783}
1784\f
1785/* Given an expression, see if it can be simplified for a particular insn
1786 code based on the values of other attributes being tested. This can
1787 eliminate nested get_attr_... calls.
1788
1789 Note that if an endless recursion is specified in the patterns, the
1790 optimization will loop. However, it will do so in precisely the cases where
1791 an infinite recursion loop could occur during compilation. It's better that
1792 it occurs here! */
1793
1794static rtx
1795simplify_test_exp (exp, insn_code, insn_index)
1796 rtx exp;
1797 int insn_code, insn_index;
1798{
1799 rtx left, right;
1800 struct attr_desc *attr;
1801 struct attr_value *av;
1802 struct insn_ent *ie;
1803 int i;
1804 rtx newexp = exp;
1805
1806 switch (GET_CODE (exp))
1807 {
1808 case AND:
1809 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1810 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1811
1812 /* If either side is an IOR and we have (eq_attr "alternative" ..")
1813 present on both sides, apply the distributive law since this will
1814 yield simplications. */
1815 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
1816 && compute_alternative_mask (left, IOR)
1817 && compute_alternative_mask (right, IOR))
1818 {
1819 if (GET_CODE (left) == IOR)
1820 {
1821 rtx tem = left;
1822 left = right;
1823 right = tem;
1824 }
1825
1826 newexp = rtx_alloc (IOR);
1827 XEXP (newexp, 0) = rtx_alloc (AND);
1828 XEXP (newexp, 1) = rtx_alloc (AND);
1829 XEXP (XEXP (newexp, 0), 0) = XEXP (XEXP (newexp, 1), 0) = left;
1830 XEXP (XEXP (newexp, 0), 1) = XEXP (right, 0);
1831 XEXP (XEXP (newexp, 1), 1) = XEXP (right, 1);
1832
1833 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1834 }
1835
1836 /* Try with the term on both sides. */
1837 right = simplify_and_tree (right, &left, insn_code, insn_index);
1838 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1839 left = simplify_and_tree (left, &right, insn_code, insn_index);
1840
1841 if (left == false_rtx || right == false_rtx)
1842 return false_rtx;
1843 else if (left == true_rtx)
1844 return right;
1845 else if (right == true_rtx)
1846 return left;
1847
1848 /* See if all or all but one of the insn's alternatives are specified
1849 in this tree. Optimize if so. */
1850
1851 else if (insn_code >= 0
1852 && (GET_CODE (left) == AND
1853 || (GET_CODE (left) == NOT
1854 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
1855 && XSTR (XEXP (left, 0), 0) == alternative_name)
1856 || GET_CODE (right) == AND
1857 || (GET_CODE (right) == NOT
1858 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
1859 && XSTR (XEXP (right, 0), 0) == alternative_name)))
1860 {
1861 i = compute_alternative_mask (exp, AND);
1862 if (i & ~insn_alternatives[insn_code])
1863 fatal ("Illegal alternative specified for pattern number %d",
1864 insn_index);
1865
1866 /* If all alternatives are excluded, this is false. */
1867 i ^= insn_alternatives[insn_code];
1868 if (i == 0)
1869 return false_rtx;
1870 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1871 {
1872 /* If just one excluded, AND a comparison with that one to the
1873 front of the tree. The others will be eliminated by
1874 optimization. We do not want to do this if the insn has one
1875 alternative and we have tested none of them! */
1876 left = make_alternative_compare (i);
1877 right = simplify_and_tree (exp, &left, insn_code, insn_index);
1878 newexp = rtx_alloc (AND);
1879 XEXP (newexp, 0) = left;
1880 XEXP (newexp, 1) = right;
1881
1882 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1883 }
1884 }
1885
1886 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1887 {
1888 newexp = rtx_alloc (AND);
1889 XEXP (newexp, 0) = left;
1890 XEXP (newexp, 1) = right;
1891 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1892 }
1893 break;
1894
1895 case IOR:
1896 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1897 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1898
1899 right = simplify_or_tree (right, &left, insn_code, insn_index);
1900 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1901 left = simplify_or_tree (left, &right, insn_code, insn_index);
1902
1903 if (right == true_rtx || left == true_rtx)
1904 return true_rtx;
1905 else if (left == false_rtx)
1906 return right;
1907 else if (right == false_rtx)
1908 return left;
1909
1910 /* Test for simple cases where the distributive law is useful. I.e.,
1911 convert (ior (and (x) (y))
1912 (and (x) (z)))
1913 to (and (x)
1914 (ior (y) (z)))
1915 */
1916
1917 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
1918 && rtx_equal_p (XEXP (left, 0), XEXP (right, 0)))
1919 {
1920 newexp = rtx_alloc (IOR);
1921 XEXP (newexp, 0) = XEXP (left, 1);
1922 XEXP (newexp, 1) = XEXP (right, 1);
1923
1924 left = XEXP (left, 0);
1925 right = newexp;
1926 newexp = rtx_alloc (AND);
1927 XEXP (newexp, 0) = left;
1928 XEXP (newexp, 1) = right;
1929 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1930 }
1931
1932 /* See if all or all but one of the insn's alternatives are specified
1933 in this tree. Optimize if so. */
1934
1935 else if (insn_code >= 0
1936 && (GET_CODE (left) == IOR
1937 || (GET_CODE (left) == EQ_ATTR
1938 && XSTR (left, 0) == alternative_name)
1939 || GET_CODE (right) == IOR
1940 || (GET_CODE (right) == EQ_ATTR
1941 && XSTR (right, 0) == alternative_name)))
1942 {
1943 i = compute_alternative_mask (exp, IOR);
1944 if (i & ~insn_alternatives[insn_code])
1945 fatal ("Illegal alternative specified for pattern number %d",
1946 insn_index);
1947
1948 /* If all alternatives are included, this is true. */
1949 i ^= insn_alternatives[insn_code];
1950 if (i == 0)
1951 return true_rtx;
1952 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1953 {
1954 /* If just one excluded, IOR a comparison with that one to the
1955 front of the tree. The others will be eliminated by
1956 optimization. We do not want to do this if the insn has one
1957 alternative and we have tested none of them! */
1958 left = make_alternative_compare (i);
1959 right = simplify_and_tree (exp, &left, insn_code, insn_index);
1960 newexp = rtx_alloc (IOR);
1961 XEXP (newexp, 0) = rtx_alloc (NOT);
1962 XEXP (XEXP (newexp, 0), 0) = left;
1963 XEXP (newexp, 1) = right;
1964
1965 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1966 }
1967 }
1968
1969 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1970 {
1971 newexp = rtx_alloc (IOR);
1972 XEXP (newexp, 0) = left;
1973 XEXP (newexp, 1) = right;
1974 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1975 }
1976 break;
1977
1978 case NOT:
1979 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1980 if (GET_CODE (left) == NOT)
1981 return XEXP (left, 0);
1982
1983 if (left == false_rtx)
1984 return true_rtx;
1985 else if (left == true_rtx)
1986 return false_rtx;
1987
1988 /* Try to apply De`Morgan's laws. */
1989 else if (GET_CODE (left) == IOR)
1990 {
1991 newexp = rtx_alloc (AND);
1992 XEXP (newexp, 0) = rtx_alloc (NOT);
1993 XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
1994 XEXP (newexp, 1) = rtx_alloc (NOT);
1995 XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
1996
1997 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1998 }
1999 else if (GET_CODE (left) == AND)
2000 {
2001 newexp = rtx_alloc (IOR);
2002 XEXP (newexp, 0) = rtx_alloc (NOT);
2003 XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
2004 XEXP (newexp, 1) = rtx_alloc (NOT);
2005 XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
2006
2007 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2008 }
2009 else if (left != XEXP (exp, 0))
2010 {
2011 newexp = rtx_alloc (NOT);
2012 XEXP (newexp, 0) = left;
2013 }
2014 break;
2015
2016 case EQ_ATTR:
2017 /* Look at the value for this insn code in the specified attribute.
2018 We normally can replace this comparison with the condition that
2019 would give this insn the values being tested for. */
2020 if (XSTR (exp, 0) != alternative_name
2021 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
2022 for (av = attr->first_value; av; av = av->next)
2023 for (ie = av->first_insn; ie; ie = ie->next)
2024 if (ie->insn_code == insn_code)
2025 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2026 }
2027
2028 /* We have already simplified this expression. Simplifying it again
2029 won't buy anything unless we weren't given a valid insn code
2030 to process (i.e., we are canonicalizing something.). */
2031 if (insn_code != -2)
2032 RTX_UNCHANGING_P (newexp) = 1;
2033
2034 return newexp;
2035}
2036\f
2037/* Optimize the attribute lists by seeing if we can determine conditional
2038 values from the known values of other attributes. This will save subroutine
2039 calls during the compilation. */
2040
2041static void
2042optimize_attrs ()
2043{
2044 struct attr_desc *attr;
2045 struct attr_value *av;
2046 struct insn_ent *ie, *nextie;
2047 rtx newexp;
2048 int something_changed = 1;
2049
2050 /* Loop until nothing changes for one iteration. */
2051 while (something_changed)
2052 {
2053 something_changed = 0;
2054 for (attr = attrs; attr; attr = attr->next)
2055 for (av = attr->first_value; av; av = av->next)
2056 for (ie = av->first_insn; ie; ie = nextie)
2057 {
2058 nextie = ie->next;
2059 if (GET_CODE (av->value) != COND)
2060 continue;
2061
2062 newexp = simplify_cond (av->value, ie->insn_code,
2063 ie->insn_index);
2064 if (newexp != av->value)
2065 {
2066 remove_insn_ent (av, ie);
2067 insert_insn_ent (get_attr_value (newexp, attr,
2068 ie->insn_code), ie);
2069 something_changed = 1;
2070 }
2071 }
2072 }
2073}
2074\f
2075/* Create table entries for DEFINE_ATTR. */
2076
2077static void
2078gen_attr (exp)
2079 rtx exp;
2080{
2081 struct attr_desc *attr;
2082 struct attr_value *av;
2083 char *name_ptr;
2084 char *p;
2085
2086 /* Make a new attribute structure. Check for duplicate by looking at
2087 attr->default_val, since it is initialized by this routine. */
2088 attr = find_attr (XSTR (exp, 0), 1);
2089 if (attr->default_val)
2090 fatal ("Duplicate definition for `%s' attribute", attr->name);
2091
2092 if (*XSTR (exp, 1) == '\0')
2093 attr->is_numeric = 1;
2094 else
2095 {
2096 name_ptr = XSTR (exp, 1);
2097 while ((p = next_comma_elt (&name_ptr)) != NULL)
2098 {
2099 av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
2100 av->value = rtx_alloc (CONST_STRING);
2101 XSTR (av->value, 0) = p;
2102 av->next = attr->first_value;
2103 attr->first_value = av;
2104 av->first_insn = NULL;
2105 av->num_insns = 0;
2106 av->has_asm_insn = 0;
2107 }
2108 }
2109
2110 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
2111 fatal ("`length' attribute must take numeric values");
2112
2113 /* Set up the default value. */
2114 check_attr_value (XEXP (exp, 2), attr);
2115 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2116}
2117\f
2118/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2119 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2120 number of alternatives as this should be checked elsewhere. */
2121
2122static int
2123count_alternatives (exp)
2124 rtx exp;
2125{
2126 int i, j, n;
2127 char *fmt;
2128
2129 if (GET_CODE (exp) == MATCH_OPERAND)
2130 return n_comma_elts (XSTR (exp, 2));
2131
2132 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2133 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2134 switch (*fmt++)
2135 {
2136 case 'e':
2137 case 'u':
2138 n = count_alternatives (XEXP (exp, i));
2139 if (n)
2140 return n;
2141 break;
2142
2143 case 'E':
2144 case 'V':
2145 if (XVEC (exp, i) != NULL)
2146 for (j = 0; j < XVECLEN (exp, i); j++)
2147 {
2148 n = count_alternatives (XVECEXP (exp, i, j));
2149 if (n)
2150 return n;
2151 }
2152 }
2153
2154 return 0;
2155}
2156\f
2157/* Returns non-zero if the given expression contains an EQ_ATTR with the
2158 `alternative' attribute. */
2159
2160static int
2161compares_alternatives_p (exp)
2162 rtx exp;
2163{
2164 int i, j;
2165 char *fmt;
2166
2167 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
2168 return 1;
2169
2170 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2171 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2172 switch (*fmt++)
2173 {
2174 case 'e':
2175 case 'u':
2176 if (compares_alternatives_p (XEXP (exp, i)))
2177 return 1;
2178 break;
2179
2180 case 'E':
2181 for (j = 0; j < XVECLEN (exp, i); j++)
2182 if (compares_alternatives_p (XVECEXP (exp, i, j)))
2183 return 1;
2184 break;
2185 }
2186
2187 return 0;
2188}
2189\f
2190/* Returns non-zero is INNER is contained in EXP. */
2191
2192static int
2193contained_in_p (inner, exp)
2194 rtx inner;
2195 rtx exp;
2196{
2197 int i, j;
2198 char *fmt;
2199
2200 if (rtx_equal_p (inner, exp))
2201 return 1;
2202
2203 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2204 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2205 switch (*fmt++)
2206 {
2207 case 'e':
2208 case 'u':
2209 if (contained_in_p (inner, XEXP (exp, i)))
2210 return 1;
2211 break;
2212
2213 case 'E':
2214 for (j = 0; j < XVECLEN (exp, i); j++)
2215 if (contained_in_p (inner, XVECEXP (exp, i, j)))
2216 return 1;
2217 break;
2218 }
2219
2220 return 0;
2221}
2222\f
2223/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2224
2225static void
2226gen_insn (exp)
2227 rtx exp;
2228{
2229 struct insn_def *id;
2230
2231 id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
2232 id->next = defs;
2233 defs = id;
2234 id->def = exp;
2235
2236 switch (GET_CODE (exp))
2237 {
2238 case DEFINE_INSN:
2239 id->insn_code = insn_code_number++;
2240 id->insn_index = insn_index_number++;
2241 id->num_alternatives = count_alternatives (exp);
2242 if (id->num_alternatives == 0)
2243 id->num_alternatives = 1;
2244 id->vec_idx = 4;
2245 break;
2246
2247 case DEFINE_PEEPHOLE:
2248 id->insn_code = insn_code_number++;
2249 id->insn_index = insn_index_number++;
2250 id->num_alternatives = count_alternatives (exp);
2251 if (id->num_alternatives == 0)
2252 id->num_alternatives = 1;
2253 id->vec_idx = 3;
2254 break;
2255
2256 case DEFINE_ASM_ATTRIBUTES:
2257 id->insn_code = -1;
2258 id->insn_index = -1;
2259 id->num_alternatives = 1;
2260 id->vec_idx = 0;
2261 got_define_asm_attributes = 1;
2262 break;
2263 }
2264}
2265\f
2266/* Process a DEFINE_DELAY. Validate the vector length, check if annul
2267 true or annul false is specified, and make a `struct delay_desc'. */
2268
2269static void
2270gen_delay (def)
2271 rtx def;
2272{
2273 struct delay_desc *delay;
2274 int i;
2275
2276 if (XVECLEN (def, 1) % 3 != 0)
2277 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2278
2279 for (i = 0; i < XVECLEN (def, 1); i += 3)
2280 {
2281 if (XVECEXP (def, 1, i + 1))
2282 have_annul_true = 1;
2283 if (XVECEXP (def, 1, i + 2))
2284 have_annul_false = 1;
2285 }
2286
2287 delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
2288 delay->def = def;
2289 delay->num = ++num_delays;
2290 delay->next = delays;
2291 delays = delay;
2292}
2293\f
2294/* Process a DEFINE_FUNCTION_UNIT.
2295
2296 This gives information about a function unit contained in the CPU.
2297 We fill in a `struct function_unit_op' and a `struct function_unit'
2298 with information used later by `expand_unit'. */
2299
2300static void
2301gen_unit (def)
2302 rtx def;
2303{
2304 struct function_unit *unit;
2305 struct function_unit_op *op;
2306
2307 /* See if we have already seen this function unit. If so, check that
2308 the multipicity and simultaneity values are the same. If not, make
2309 a structure for this function unit. */
2310 for (unit = units; unit; unit = unit->next)
2311 if (! strcmp (unit->name, XSTR (def, 0)))
2312 {
2313 if (unit->multiplicity != XINT (def, 1)
2314 || unit->simultaneity != XINT (def, 2))
2315 fatal ("Differing specifications given for `%s' function unit.",
2316 unit->name);
2317 break;
2318 }
2319
2320 if (unit == 0)
2321 {
2322 unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
2323 unit->name = XSTR (def, 0);
2324 unit->multiplicity = XINT (def, 1);
2325 unit->simultaneity = XINT (def, 2);
2326 unit->num = num_units++;
2327 unit->num_opclasses = 0;
2328 unit->condexp = false_rtx;
2329 unit->ops = 0;
2330 unit->next = units;
2331 units = unit;
2332 }
2333
2334 /* Make a new operation class structure entry and initialize it. */
2335 op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
2336 op->condexp = XEXP (def, 3);
2337 op->num = unit->num_opclasses++;
2338 op->ready = XINT (def, 4);
2339 op->next = unit->ops;
2340 unit->ops = op;
2341
2342 /* Set our busy expression based on whether or not an optional conflict
2343 vector was specified. */
2344 if (XVEC (def, 6))
2345 {
2346 /* Compute the IOR of all the specified expressions. */
2347 rtx orexp = false_rtx;
2348 int i;
2349
2350 for (i = 0; i < XVECLEN (def, 6); i++)
2351 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
2352
2353 op->busyexp = rtx_alloc (IF_THEN_ELSE);
2354 XEXP (op->busyexp, 0) = orexp;
2355 XEXP (op->busyexp, 1) = make_numeric_value (XINT (def, 5));
2356 XEXP (op->busyexp, 2) = make_numeric_value (0);
2357 }
2358 else
2359 op->busyexp = make_numeric_value (XINT (def, 5));
2360
2361 /* Merge our conditional into that of the function unit so we can determine
2362 which insns are used by the function unit. */
2363 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
2364}
2365\f
2366/* Given a piece of RTX, print a C expression to test it's truth value.
2367 We use AND and IOR both for logical and bit-wise operations, so
2368 interpret them as logical unless they are inside a comparison expression.
2369 The second operand of this function will be non-zero in that case. */
2370
2371static void
2372write_test_expr (exp, in_comparison)
2373 rtx exp;
2374 int in_comparison;
2375{
2376 int comparison_operator = 0;
2377 RTX_CODE code;
2378 struct attr_desc *attr;
2379
2380 /* In order not to worry about operator precedence, surround our part of
2381 the expression with parentheses. */
2382
2383 printf ("(");
2384 code = GET_CODE (exp);
2385 switch (code)
2386 {
2387 /* Binary operators. */
2388 case EQ: case NE:
2389 case GE: case GT: case GEU: case GTU:
2390 case LE: case LT: case LEU: case LTU:
2391 comparison_operator = 1;
2392
2393 case PLUS: case MINUS: case MULT: case DIV: case MOD:
2394 case AND: case IOR: case XOR:
2395 case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
2396 write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
2397 switch (code)
2398 {
2399 case EQ:
2400 printf (" == ");
2401 break;
2402 case NE:
2403 printf (" != ");
2404 break;
2405 case GE:
2406 printf (" >= ");
2407 break;
2408 case GT:
2409 printf (" > ");
2410 break;
2411 case GEU:
2412 printf (" >= (unsigned) ");
2413 break;
2414 case GTU:
2415 printf (" > (unsigned) ");
2416 break;
2417 case LE:
2418 printf (" <= ");
2419 break;
2420 case LT:
2421 printf (" < ");
2422 break;
2423 case LEU:
2424 printf (" <= (unsigned) ");
2425 break;
2426 case LTU:
2427 printf (" < (unsigned) ");
2428 break;
2429 case PLUS:
2430 printf (" + ");
2431 break;
2432 case MINUS:
2433 printf (" - ");
2434 break;
2435 case MULT:
2436 printf (" * ");
2437 break;
2438 case DIV:
2439 printf (" / ");
2440 break;
2441 case MOD:
2442 printf (" % ");
2443 break;
2444 case AND:
2445 if (in_comparison)
2446 printf (" & ");
2447 else
2448 printf (" && ");
2449 break;
2450 case IOR:
2451 if (in_comparison)
2452 printf (" | ");
2453 else
2454 printf (" || ");
2455 break;
2456 case XOR:
2457 printf (" ^ ");
2458 break;
2459 case LSHIFT:
2460 case ASHIFT:
2461 printf (" << ");
2462 break;
2463 case LSHIFTRT:
2464 case ASHIFTRT:
2465 printf (" >> ");
2466 break;
2467 }
2468
2469 write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
2470 break;
2471
2472 case NOT:
2473 /* Special-case (not (eq_attrq "alternative" "x")) */
2474 if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2475 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2476 {
2477 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
2478 break;
2479 }
2480
2481 /* Otherwise, fall through to normal unary operator. */
2482
2483 /* Unary operators. */
2484 case ABS: case NEG:
2485 switch (code)
2486 {
2487 case NOT:
2488 if (in_comparison)
2489 printf ("~ ");
2490 else
2491 printf ("! ");
2492 break;
2493 case ABS:
2494 printf ("abs ");
2495 break;
2496 case NEG:
2497 printf ("-");
2498 break;
2499 }
2500
2501 write_test_expr (XEXP (exp, 0), in_comparison);
2502 break;
2503
2504 /* Comparison test of an attribute with a value. Most of these will
2505 have been removed by optimization. Handle "alternative"
2506 specially and give error if EQ_ATTR present inside a comparison. */
2507 case EQ_ATTR:
2508 if (in_comparison)
2509 fatal ("EQ_ATTR not valid inside comparison");
2510
2511 if (XSTR (exp, 0) == alternative_name)
2512 {
2513 printf ("which_alternative == %s", XSTR (exp, 1));
2514 break;
2515 }
2516
2517 attr = find_attr (XSTR (exp, 0), 0);
2518 if (! attr) abort ();
2519 printf ("get_attr_%s (insn) == ", attr->name);
2520 write_attr_valueq (attr, XSTR (exp, 1));
2521 break;
2522
2523 /* See if an operand matches a predicate. */
2524 case MATCH_OPERAND:
2525 /* If only a mode is given, just ensure the mode matches the operand.
2526 If neither a mode nor predicate is given, error. */
2527 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
2528 {
2529 if (GET_MODE (exp) == VOIDmode)
2530 fatal ("Null MATCH_OPERAND specified as test");
2531 else
2532 printf ("GET_MODE (operands[%d]) == %smode",
2533 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2534 }
2535 else
2536 printf ("%s (operands[%d], %smode)",
2537 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2538 break;
2539
2540 /* Constant integer. */
2541 case CONST_INT:
2542 printf ("%d", XINT (exp, 0));
2543 break;
2544
2545 /* A random C expression. */
2546 case SYMBOL_REF:
2547 printf ("%s", XSTR (exp, 0));
2548 break;
2549
2550 /* The address of the branch target. */
2551 case MATCH_DUP:
2552 printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
2553 break;
2554
2555 /* The address of the current insn. It would be more consistent with
2556 other usage to make this the address of the NEXT insn, but this gets
2557 too confusing because of the ambiguity regarding the length of the
2558 current insn. */
2559 case PC:
2560 printf ("insn_current_address");
2561 break;
2562
2563 default:
2564 fatal ("bad RTX code `%s' in attribute calculation\n",
2565 GET_RTX_NAME (code));
2566 }
2567
2568 printf (")");
2569}
2570\f
2571/* Given an attribute value, return the maximum CONST_STRING argument
2572 encountered. It is assumed that they are all numeric. */
2573
2574static int
2575max_attr_value (exp)
2576 rtx exp;
2577{
2578 int current_max = 0;
2579 int n;
2580 int i;
2581
2582 if (GET_CODE (exp) == CONST_STRING)
2583 return atoi (XSTR (exp, 0));
2584
2585 else if (GET_CODE (exp) == COND)
2586 {
2587 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2588 {
2589 n = max_attr_value (XVECEXP (exp, 0, i + 1));
2590 if (n > current_max)
2591 current_max = n;
2592 }
2593
2594 n = max_attr_value (XEXP (exp, 1));
2595 if (n > current_max)
2596 current_max = n;
2597 }
2598
2599 else
2600 abort ();
2601
2602 return current_max;
2603}
2604\f
2605/* Scan an attribute value, possibly a conditional, and record what actions
2606 will be required to do any conditional tests in it.
2607
2608 Specifically, set
2609 `must_extract' if we need to extract the insn operands
2610 `must_constrain' if we must compute `which_alternative'
2611 `address_used' if an address expression was used
2612 */
2613
2614static void
2615walk_attr_value (exp)
2616 rtx exp;
2617{
2618 register int i, j;
2619 register char *fmt;
2620 RTX_CODE code;
2621
2622 if (exp == NULL)
2623 return;
2624
2625 code = GET_CODE (exp);
2626 switch (code)
2627 {
2628 case SYMBOL_REF:
2629 /* Since this is an arbitrary expression, it can look at anything. */
2630 must_extract = must_constrain = 1;
2631 return;
2632
2633 case MATCH_OPERAND:
2634 must_extract = 1;
2635 return;
2636
2637 case EQ_ATTR:
2638 if (XSTR (exp, 0) == alternative_name)
2639 must_extract = must_constrain = 1;
2640 return;
2641
2642 case MATCH_DUP:
2643 case PC:
2644 address_used = 1;
2645 return;
2646 }
2647
2648 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
2649 switch (*fmt++)
2650 {
2651 case 'e':
2652 case 'u':
2653 walk_attr_value (XEXP (exp, i));
2654 break;
2655
2656 case 'E':
2657 if (XVEC (exp, i) != NULL)
2658 for (j = 0; j < XVECLEN (exp, i); j++)
2659 walk_attr_value (XVECEXP (exp, i, j));
2660 break;
2661 }
2662}
2663\f
2664/* Write out a function to obtain the attribute for a given INSN. */
2665
2666static void
2667write_attr_get (attr)
2668 struct attr_desc *attr;
2669{
2670 struct attr_value *av, *common_av;
2671
2672 /* Find the most used attribute value. Handle that as the `default' of the
2673 switch we will generate. */
2674 common_av = find_most_used (attr);
2675
2676 /* Write out start of function, then all values with explicit `case' lines,
2677 then a `default', then the value with the most uses. */
2678 if (attr->is_numeric)
2679 printf ("int\n");
2680 else
2681 printf ("enum attr_%s\n", attr->name);
2682
2683 /* If the attribute name starts with a star, the remainder is the name of
2684 the subroutine to use, instead of `get_attr_...'. */
2685 if (attr->name[0] == '*')
2686 printf ("%s (insn)\n", &attr->name[1]);
2687 else
2688 printf ("get_attr_%s (insn)\n", attr->name);
2689 printf (" rtx insn;\n");
2690 printf ("{\n");
2691 printf (" switch (recog_memoized (insn))\n");
2692 printf (" {\n");
2693
2694 for (av = attr->first_value; av; av = av->next)
2695 if (av != common_av)
2696 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
2697
2698 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
2699 printf (" }\n}\n\n");
2700}
2701\f
2702/* Given an AND tree of known true terms (because we are inside an `if' with
2703 that as the condition or are in an `else' clause) and an expression,
2704 replace any known true terms with TRUE. Use `simplify_and_tree' to do
2705 the bulk of the work. */
2706
2707static rtx
2708eliminate_known_true (known_true, exp, insn_code, insn_index)
2709 rtx known_true;
2710 rtx exp;
2711 int insn_code, insn_index;
2712{
2713 rtx term;
2714
2715 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
2716
2717 if (GET_CODE (known_true) == AND)
2718 {
2719 exp = eliminate_known_true (XEXP (known_true, 0), exp,
2720 insn_code, insn_index);
2721 exp = eliminate_known_true (XEXP (known_true, 1), exp,
2722 insn_code, insn_index);
2723 }
2724 else
2725 {
2726 term = known_true;
2727 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
2728 }
2729
2730 return exp;
2731}
2732\f
2733/* Write out a series of tests and assignment statements to perform tests and
2734 sets of an attribute value. We are passed an indentation amount and prefix
2735 and suffix strings to write around each attribute value (e.g., "return"
2736 and ";"). */
2737
2738static void
2739write_attr_set (attr, indent, value, prefix, suffix, known_true,
2740 insn_code, insn_index)
2741 struct attr_desc *attr;
2742 int indent;
2743 rtx value;
2744 char *prefix;
2745 char *suffix;
2746 rtx known_true;
2747 int insn_code, insn_index;
2748{
2749 if (GET_CODE (value) == CONST_STRING)
2750 {
2751 write_indent (indent);
2752 printf ("%s ", prefix);
2753 write_attr_value (attr, value);
2754 printf ("%s\n", suffix);
2755 }
2756 else if (GET_CODE (value) == COND)
2757 {
2758 /* Assume the default value will be the default of the COND unless we
2759 find an always true expression. */
2760 rtx default_val = XEXP (value, 1);
2761 rtx our_known_true = known_true;
2762 rtx newexp;
2763 int first_if = 1;
2764 int i;
2765
2766 for (i = 0; i < XVECLEN (value, 0); i += 2)
2767 {
2768 rtx testexp;
2769 rtx inner_true;
2770
2771 testexp = eliminate_known_true (our_known_true,
2772 XVECEXP (value, 0, i),
2773 insn_code, insn_index);
2774 newexp = rtx_alloc (NOT);
2775 XEXP (newexp, 0) = testexp;
2776 newexp = insert_right_side (AND, our_known_true, newexp,
2777 insn_code, insn_index);
2778
2779 /* If the test expression is always true or if the next `known_true'
2780 expression is always false, this is the last case, so break
2781 out and let this value be the `else' case. */
2782 if (testexp == true_rtx || newexp == false_rtx)
2783 {
2784 default_val = XVECEXP (value, 0, i + 1);
2785 break;
2786 }
2787
2788 /* Compute the expression to pass to our recursive call as being
2789 known true. */
2790 inner_true = insert_right_side (AND, our_known_true,
2791 testexp, insn_code, insn_index);
2792
2793 /* If this is always false, skip it. */
2794 if (inner_true == false_rtx)
2795 continue;
2796
2797 write_indent (indent);
2798 printf ("%sif ", first_if ? "" : "else ");
2799 first_if = 0;
2800 write_test_expr (testexp, 0);
2801 printf ("\n");
2802 write_indent (indent + 2);
2803 printf ("{\n");
2804
2805 write_attr_set (attr, indent + 4,
2806 XVECEXP (value, 0, i + 1), prefix, suffix,
2807 inner_true, insn_code, insn_index);
2808 write_indent (indent + 2);
2809 printf ("}\n");
2810 our_known_true = newexp;
2811 }
2812
2813 if (! first_if)
2814 {
2815 write_indent (indent);
2816 printf ("else\n");
2817 write_indent (indent + 2);
2818 printf ("{\n");
2819 }
2820
2821 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
2822 prefix, suffix, our_known_true, insn_code, insn_index);
2823
2824 if (! first_if)
2825 {
2826 write_indent (indent + 2);
2827 printf ("}\n");
2828 }
2829 }
2830 else
2831 abort ();
2832}
2833\f
2834/* Write out the computation for one attribute value. */
2835
2836static void
2837write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
2838 struct attr_desc *attr;
2839 struct attr_value *av;
2840 int write_case_lines;
2841 char *prefix, *suffix;
2842 int indent;
2843 rtx known_true;
2844{
2845 struct insn_ent *ie;
2846
2847 if (av->num_insns == 0)
2848 return;
2849
2850 if (av->has_asm_insn)
2851 {
2852 write_indent (indent);
2853 printf ("case -1:\n");
2854 write_indent (indent + 2);
2855 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
2856 write_indent (indent + 2);
2857 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
2858 write_indent (indent + 2);
2859 printf (" fatal_insn_not_found (insn);\n");
2860 }
2861
2862 if (write_case_lines)
2863 {
2864 for (ie = av->first_insn; ie; ie = ie->next)
2865 if (ie->insn_code != -1)
2866 {
2867 write_indent (indent);
2868 printf ("case %d:\n", ie->insn_code);
2869 }
2870 }
2871 else
2872 {
2873 write_indent (indent);
2874 printf ("default:\n");
2875 }
2876
2877 /* See what we have to do to handle output this value. */
2878 must_extract = must_constrain = address_used = 0;
2879 walk_attr_value (av->value);
2880
2881 if (must_extract)
2882 {
2883 write_indent (indent + 2);
2884 printf ("insn_extract (insn);\n");
2885 }
2886
2887 if (must_constrain)
2888 {
2889#ifdef REGISTER_CONSTRAINTS
2890 write_indent (indent + 2);
2891 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
2892 write_indent (indent + 2);
2893 printf (" fatal_insn_not_found (insn);\n");
2894#endif
2895 }
2896
2897 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
2898 known_true, av->first_insn->insn_code,
2899 av->first_insn->insn_index);
2900
2901 if (strncmp (prefix, "return", 6))
2902 {
2903 write_indent (indent + 2);
2904 printf ("break;\n");
2905 }
2906 printf ("\n");
2907}
2908\f
2909/* Utilities to write names in various forms. */
2910
2911static void
2912write_attr_valueq (attr, s)
2913 struct attr_desc *attr;
2914 char *s;
2915{
2916 if (attr->is_numeric)
2917 printf ("%s", s);
2918 else
2919 {
2920 write_upcase (attr->name);
2921 printf ("_");
2922 write_upcase (s);
2923 }
2924}
2925
2926static void
2927write_attr_value (attr, value)
2928 struct attr_desc *attr;
2929 rtx value;
2930{
2931 if (GET_CODE (value) != CONST_STRING)
2932 abort ();
2933
2934 write_attr_valueq (attr, XSTR (value, 0));
2935}
2936
2937static void
2938write_upcase (str)
2939 char *str;
2940{
2941 while (*str)
2942 if (*str < 'a' || *str > 'z')
2943 printf ("%c", *str++);
2944 else
2945 printf ("%c", *str++ - 'a' + 'A');
2946}
2947
2948static void
2949write_indent (indent)
2950 int indent;
2951{
2952 for (; indent > 8; indent -= 8)
2953 printf ("\t");
2954
2955 for (; indent; indent--)
2956 printf (" ");
2957}
2958\f
2959/* Write a subroutine that is given an insn that requires a delay slot, a
2960 delay slot ordinal, and a candidate insn. It returns non-zero if the
2961 candidate can be placed in the specified delay slot of the insn.
2962
2963 We can write as many as three subroutines. `eligible_for_delay'
2964 handles normal delay slots, `eligible_for_annul_true' indicates that
2965 the specified insn can be annulled if the branch is true, and likewise
2966 for `eligible_for_annul_false'.
2967
2968 KIND is a string distingushing these three cases ("delay", "annul_true",
2969 or "annul_false"). */
2970
2971static void
2972write_eligible_delay (kind)
2973 char *kind;
2974{
2975 struct delay_desc *delay;
2976 int max_slots;
2977 char str[50];
2978 struct attr_desc *attr;
2979 struct attr_value *av, *common_av;
2980 int i;
2981
2982 /* Compute the maximum number of delay slots required. We use the delay
2983 ordinal times this number plus one, plus the slot number as an index into
2984 the appropriate predicate to test. */
2985
2986 for (delay = delays, max_slots = 0; delay; delay = delay->next)
2987 if (XVECLEN (delay->def, 1) / 3 > max_slots)
2988 max_slots = XVECLEN (delay->def, 1) / 3;
2989
2990 /* Write function prelude. */
2991
2992 printf ("int\n");
2993 printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
2994 printf (" rtx delay_insn;\n");
2995 printf (" int slot;\n");
2996 printf (" rtx candidate_insn;\n");
2997 printf ("{\n");
2998 printf (" rtx insn;\n");
2999 printf ("\n");
3000 printf (" if (slot >= %d)\n", max_slots);
3001 printf (" abort ();\n");
3002 printf ("\n");
3003
3004 /* If more than one delay type, find out which type the delay insn is. */
3005
3006 if (num_delays > 1)
3007 {
3008 sprintf (str, "*delay_type", kind);
3009 attr = find_attr (str, 0);
3010 if (! attr) abort ();
3011 common_av = find_most_used (attr);
3012
3013 printf (" insn = delay_insn;\n");
3014 printf (" switch (recog_memoized (insn))\n");
3015 printf (" {\n");
3016
3017 sprintf (str, " * %d;\n break;", max_slots);
3018 for (av = attr->first_value; av; av = av->next)
3019 if (av != common_av)
3020 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
3021
3022 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
3023 printf (" }\n\n");
3024
3025 /* Ensure matched. Otherwise, shouldn't have been called. */
3026 printf (" if (slot < %d)\n", max_slots);
3027 printf (" abort ();\n\n");
3028 }
3029
3030 /* If just one type of delay slot, write simple switch. */
3031 if (num_delays == 1 && max_slots == 1)
3032 {
3033 printf (" insn = candidate_insn;\n");
3034 printf (" switch (recog_memoized (insn))\n");
3035 printf (" {\n");
3036
3037 attr = find_attr ("*delay_1_0", 0);
3038 if (! attr) abort ();
3039 common_av = find_most_used (attr);
3040
3041 for (av = attr->first_value; av; av = av->next)
3042 if (av != common_av)
3043 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3044
3045 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3046 printf (" }\n");
3047 }
3048
3049 else
3050 {
3051 /* Write a nested CASE. The first indicates which condition we need to
3052 test, and the inner CASE tests the condition. */
3053 printf (" insn = candidate_insn;\n");
3054 printf (" switch (slot)\n");
3055 printf (" {\n");
3056
3057 for (delay = delays; delay; delay = delay->next)
3058 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
3059 {
3060 printf (" case %d:\n",
3061 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
3062 printf (" switch (recog_memoized (insn))\n");
3063 printf ("\t{\n");
3064
3065 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
3066 attr = find_attr (str, 0);
3067 if (! attr) abort ();
3068 common_av = find_most_used (attr);
3069
3070 for (av = attr->first_value; av; av = av->next)
3071 if (av != common_av)
3072 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
3073
3074 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
3075 printf (" }\n");
3076 }
3077
3078 printf (" default:\n");
3079 printf (" abort ();\n");
3080 printf (" }\n");
3081 }
3082
3083 printf ("}\n\n");
3084}
3085\f
3086/* Write routines to compute conflict cost for function units. Then write a
3087 table describing the available function units. */
3088
3089static void
3090write_function_unit_info ()
3091{
3092 struct function_unit *unit;
3093 struct attr_desc *case_attr, *attr;
3094 struct attr_value *av, *common_av;
3095 rtx value;
3096 char *str;
3097 int using_case;
3098 int i;
3099
3100 /* Write out conflict routines for function units. Don't bother writing
3101 one if there is only one busy value. */
3102
3103 for (unit = units; unit; unit = unit->next)
3104 {
3105 /* See if only one case exists and if there is a constant value for
3106 that case. If so, we don't need a function. */
3107 str = (char *) xmalloc (strlen (unit->name) + 10);
3108 sprintf (str, "*%s_cases", unit->name);
3109 attr = find_attr (str, 0);
3110 if (! attr) abort ();
3111 value = find_single_value (attr);
3112 if (value && GET_CODE (value) == CONST_STRING)
3113 {
3114 sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
3115 attr = find_attr (str, 0);
3116 if (! attr) abort ();
3117 value = find_single_value (attr);
3118 if (value && GET_CODE (value) == CONST_STRING)
3119 {
3120 unit->needs_conflict_function = 0;
3121 unit->default_cost = value;
3122 continue;
3123 }
3124 }
3125
3126 /* The function first computes the case from the candidate insn. */
3127 unit->needs_conflict_function = 1;
3128 unit->default_cost = make_numeric_value (0);
3129
3130 printf ("static int\n");
3131 printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3132 unit->name);
3133 printf (" rtx executing_insn;\n");
3134 printf (" rtx candidate_insn;\n");
3135 printf ("{\n");
3136 printf (" rtx insn;\n");
3137 printf (" int casenum;\n\n");
3138 printf (" insn = candidate_insn;\n");
3139 printf (" switch (recog_memoized (insn))\n");
3140 printf (" {\n");
3141
3142 /* Write the `switch' statement to get the case value. */
3143 sprintf (str, "*%s_cases", unit->name);
3144 case_attr = find_attr (str, 0);
3145 if (! case_attr) abort ();
3146 common_av = find_most_used (case_attr);
3147
3148 for (av = case_attr->first_value; av; av = av->next)
3149 if (av != common_av)
3150 write_attr_case (case_attr, av, 1,
3151 "casenum =", ";", 4, unit->condexp);
3152
3153 write_attr_case (case_attr, common_av, 0,
3154 "casenum =", ";", 4, unit->condexp);
3155 printf (" }\n\n");
3156
3157 /* Now write an outer switch statement on each case. Then write
3158 the tests on the executing function within each. */
3159 printf (" insn = executing_insn;\n");
3160 printf (" switch (casenum)\n");
3161 printf (" {\n");
3162
3163 for (i = 0; i < unit->num_opclasses; i++)
3164 {
3165 /* Ensure using this case. */
3166 using_case = 0;
3167 for (av = case_attr->first_value; av; av = av->next)
3168 if (av->num_insns
3169 && contained_in_p (make_numeric_value (i), av->value))
3170 using_case = 1;
3171
3172 if (! using_case)
3173 continue;
3174
3175 printf (" case %d:\n", i);
3176 sprintf (str, "*%s_case_%d", unit->name, i);
3177 attr = find_attr (str, 0);
3178 if (! attr) abort ();
3179
3180 /* If single value, just write it. */
3181 value = find_single_value (attr);
3182 if (value)
3183 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
3184 else
3185 {
3186 common_av = find_most_used (attr);
3187 printf (" switch (recog_memoized (insn))\n");
3188 printf ("\t{\n");
3189
3190 for (av = attr->first_value; av; av = av->next)
3191 if (av != common_av)
3192 write_attr_case (attr, av, 1,
3193 "return", ";", 8, unit->condexp);
3194
3195 write_attr_case (attr, common_av, 0,
3196 "return", ";", 8, unit->condexp);
3197 printf (" }\n\n");
3198 }
3199 }
3200
3201 printf (" }\n}\n\n");
3202 }
3203
3204 /* Now that all functions have been written, write the table describing
3205 the function units. The name is included for documenation purposes
3206 only. */
3207
3208 printf ("struct function_unit_desc function_units[] = {\n");
3209
3210 for (unit = units; unit; unit = unit->next)
3211 {
3212 printf (" {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3213 unit->name, 1 << unit->num, unit->multiplicity,
3214 unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
3215
3216 if (unit->needs_conflict_function)
3217 printf ("%s_unit_conflict_cost", unit->name);
3218 else
3219 printf ("0");
3220
3221 printf ("}, \n");
3222 }
3223
3224 printf ("};\n\n");
3225}
3226\f
3227/* This page contains miscellaneous utility routines. */
3228
3229/* Given a string, return the number of comma-separated elements in it.
3230 Return 0 for the null string. */
3231
3232static int
3233n_comma_elts (s)
3234 char *s;
3235{
3236 int n;
3237
3238 if (*s == '\0')
3239 return 0;
3240
3241 for (n = 1; *s; s++)
3242 if (*s == ',')
3243 n++;
3244
3245 return n;
3246}
3247
3248/* Given a pointer to a (char *), return a malloc'ed string containing the
3249 next comma-separated element. Advance the pointer to after the string
3250 scanned, or the end-of-string. Return NULL if at end of string. */
3251
3252static char *
3253next_comma_elt (pstr)
3254 char **pstr;
3255{
3256 char *out_str;
3257 char *p;
3258
3259 if (**pstr == '\0')
3260 return NULL;
3261
3262 /* Find end of string to compute length. */
3263 for (p = *pstr; *p != ',' && *p != '\0'; p++)
3264 ;
3265
3266 out_str = (char *) xmalloc (p - *pstr + 1);
3267 for (p = out_str; **pstr != ',' && **pstr != '\0'; (*pstr)++)
3268 *p++ = **pstr;
3269
3270 *p++ = '\0';
3271 if (**pstr == ',')
3272 (*pstr)++;
3273
3274 return out_str;
3275}
3276
3277/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
3278 is non-zero, build a new attribute, if one does not exist. */
3279
3280static struct attr_desc *
3281find_attr (name, create)
3282 char *name;
3283 int create;
3284{
3285 struct attr_desc *attr;
3286 char *new_name;
3287
3288 /* Before we resort to using `strcmp', see if the string address matches
3289 anywhere. In most cases, it should have been canonicalized to do so. */
3290 if (name == alternative_name)
3291 return NULL;
3292
3293 for (attr = attrs; attr; attr = attr->next)
3294 if (name == attr->name)
3295 return attr;
3296
3297 /* Otherwise, do it the slow way. */
3298 for (attr = attrs; attr; attr = attr->next)
3299 if (! strcmp (name, attr->name))
3300 return attr;
3301
3302 if (! create)
3303 return NULL;
3304
3305 new_name = (char *) xmalloc (strlen (name) + 1);
3306 strcpy (new_name, name);
3307
3308 attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
3309 attr->name = new_name;
3310 attr->first_value = attr->default_val = NULL;
3311 attr->is_numeric = attr->is_special = 0;
3312 attr->next = attrs;
3313 attrs = attr;
3314
3315 return attr;
3316}
3317
3318/* Create internal attribute with the given default value. */
3319
3320static void
3321make_internal_attr (name, value, special)
3322 char *name;
3323 rtx value;
3324 int special;
3325{
3326 struct attr_desc *attr;
3327
3328 attr = find_attr (name, 1);
3329 if (attr->default_val)
3330 abort ();
3331
3332 attr->is_numeric = 1;
3333 attr->is_special = special;
3334 attr->default_val = get_attr_value (value, attr, -2);
3335}
3336
3337/* Find the most used value of an attribute. */
3338
3339static struct attr_value *
3340find_most_used (attr)
3341 struct attr_desc *attr;
3342{
3343 struct attr_value *av;
3344 struct attr_value *most_used;
3345 int nuses;
3346
3347 most_used = NULL;
3348 nuses = -1;
3349
3350 for (av = attr->first_value; av; av = av->next)
3351 if (av->num_insns > nuses)
3352 nuses = av->num_insns, most_used = av;
3353
3354 return most_used;
3355}
3356
3357/* If an attribute only has a single value used, return it. Otherwise
3358 return NULL. */
3359
3360static rtx
3361find_single_value (attr)
3362 struct attr_desc *attr;
3363{
3364 struct attr_value *av;
3365 rtx unique_value;
3366
3367 unique_value = NULL;
3368 for (av = attr->first_value; av; av = av->next)
3369 if (av->num_insns)
3370 {
3371 if (unique_value)
3372 return NULL;
3373 else
3374 unique_value = av->value;
3375 }
3376
3377 return unique_value;
3378}
3379
3380/* Return (attr_value "n") */
3381
3382static rtx
3383make_numeric_value (n)
3384 int n;
3385{
3386 static rtx int_values[20];
3387 rtx exp;
3388
3389 if (n < 0)
3390 abort ();
3391
3392 if (n < 20 && int_values[n])
3393 return int_values[n];
3394
3395 exp = rtx_alloc (CONST_STRING);
3396 XSTR (exp, 0) = (char *) xmalloc ((n < 1000 ? 4
3397 : HOST_BITS_PER_INT * 3 / 10 + 3));
3398 sprintf (XSTR (exp, 0), "%d", n);
3399
3400 if (n < 20)
3401 int_values[n] = exp;
3402
3403 return exp;
3404}
3405\f
3406char *
3407xrealloc (ptr, size)
3408 char *ptr;
3409 unsigned size;
3410{
3411 char *result = (char *) realloc (ptr, size);
3412 if (!result)
3413 fatal ("virtual memory exhausted");
3414 return result;
3415}
3416
3417char *
3418xmalloc (size)
3419 unsigned size;
3420{
3421 register char *val = (char *) malloc (size);
3422
3423 if (val == 0)
3424 fatal ("virtual memory exhausted");
3425 return val;
3426}
3427
3428static void
3429fatal (s, a1, a2)
3430 char *s;
3431{
3432 fprintf (stderr, "genattrtab: ");
3433 fprintf (stderr, s, a1, a2);
3434 fprintf (stderr, "\n");
3435 exit (FATAL_EXIT_CODE);
3436}
3437
3438/* More 'friendly' abort that prints the line and file.
3439 config.h can #define abort fancy_abort if you like that sort of thing. */
3440
3441void
3442fancy_abort ()
3443{
3444 fatal ("Internal gcc abort.");
3445}
3446\f
3447int
3448main (argc, argv)
3449 int argc;
3450 char **argv;
3451{
3452 rtx desc;
3453 FILE *infile;
3454 extern rtx read_rtx ();
3455 register int c;
3456 struct attr_desc *attr;
3457 struct attr_value *av;
3458 struct insn_def *id;
3459 rtx tem;
3460
3461 obstack_init (rtl_obstack);
3462
3463 if (argc <= 1)
3464 fatal ("No input file name.");
3465
3466 infile = fopen (argv[1], "r");
3467 if (infile == 0)
3468 {
3469 perror (argv[1]);
3470 exit (FATAL_EXIT_CODE);
3471 }
3472
3473 init_rtl ();
3474
3475 /* Set up true and false rtx's */
3476 true_rtx = rtx_alloc (CONST_INT);
3477 false_rtx = rtx_alloc (CONST_INT);
3478 XINT (true_rtx, 0) = 1;
3479 XINT (false_rtx, 0) = 0;
3480 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
3481
3482 printf ("/* Generated automatically by the program `genattrtab'\n\
3483from the machine description file `md'. */\n\n");
3484
3485 /* Read the machine description. */
3486
3487 while (1)
3488 {
3489 c = read_skip_spaces (infile);
3490 if (c == EOF)
3491 break;
3492 ungetc (c, infile);
3493
3494 desc = read_rtx (infile);
3495 if (GET_CODE (desc) == DEFINE_INSN
3496 || GET_CODE (desc) == DEFINE_PEEPHOLE
3497 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
3498 gen_insn (desc);
3499
3500 else if (GET_CODE (desc) == DEFINE_EXPAND)
3501 insn_code_number++, insn_index_number++;
3502
3503 else if (GET_CODE (desc) == DEFINE_SPLIT)
3504 insn_code_number++, insn_index_number++;
3505
3506 else if (GET_CODE (desc) == DEFINE_ATTR)
3507 {
3508 gen_attr (desc);
3509 insn_index_number++;
3510 }
3511
3512 else if (GET_CODE (desc) == DEFINE_DELAY)
3513 {
3514 gen_delay (desc);
3515 insn_index_number++;
3516 }
3517
3518 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
3519 {
3520 gen_unit (desc);
3521 insn_index_number++;
3522 }
3523 }
3524
3525 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
3526 if (! got_define_asm_attributes)
3527 {
3528 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
3529 XVEC (tem, 0) = rtvec_alloc (0);
3530 gen_insn (tem);
3531 }
3532
3533 /* Expand DEFINE_DELAY information into new attribute. */
3534 if (num_delays)
3535 expand_delays ();
3536
3537 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
3538 if (num_units)
3539 expand_units ();
3540
3541 printf ("#include \"config.h\"\n");
3542 printf ("#include \"rtl.h\"\n");
3543 printf ("#include \"insn-config.h\"\n");
3544 printf ("#include \"recog.h\"\n");
3545 printf ("#include \"regs.h\"\n");
3546 printf ("#include \"real.h\"\n");
3547 printf ("#include \"output.h\"\n");
3548 printf ("#include \"insn-attr.h\"\n");
3549 printf ("\n");
3550 printf ("#define operands recog_operand\n\n");
3551
3552 /* Make `insn_alternatives'. */
3553 insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
3554 for (id = defs; id; id = id->next)
3555 if (id->insn_code >= 0)
3556 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
3557
3558 /* Prepare to write out attribute subroutines by checking everything stored
3559 away and building the attribute cases. */
3560
3561 check_defs ();
3562 for (attr = attrs; attr; attr = attr->next)
3563 {
3564 check_attr_value (attr->default_val->value, attr);
3565 fill_attr (attr);
3566 }
3567
3568 /* Construct extra attributes for `length'. */
3569 make_length_attrs ();
3570
3571 /* Perform any possible optimizations to speed up compilation. */
3572 optimize_attrs ();
3573
3574 /* Now write out all the `gen_attr_...' routines. Do these before the
3575 special routines (specifically before write_function_unit_info), so
3576 that they get defined before they are used. */
3577
3578 for (attr = attrs; attr; attr = attr->next)
3579 {
3580 if (! attr->is_special)
3581 write_attr_get (attr);
3582 }
3583
3584 /* Write out delay eligibility information, if DEFINE_DELAY present.
3585 (The function to compute the number of delay slots will be written
3586 below.) */
3587 if (num_delays)
3588 {
3589 write_eligible_delay ("delay");
3590 if (have_annul_true)
3591 write_eligible_delay ("annul_true");
3592 if (have_annul_false)
3593 write_eligible_delay ("annul_false");
3594 }
3595
3596 /* Write out information about function units. */
3597 if (num_units)
3598 write_function_unit_info ();
3599
3600 fflush (stdout);
3601 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
3602 /* NOTREACHED */
3603 return 0;
3604}