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