]> gcc.gnu.org Git - gcc.git/blame - gcc/genoutput.c
genattr.c (function_unit_desc): Constify a char*.
[gcc.git] / gcc / genoutput.c
CommitLineData
9db4e0ec 1/* Generate code from to output assembler insns as recognized from rtl.
efd59a33 2 Copyright (C) 1987, 88, 92, 94-95, 97-98, 1999 Free Software Foundation, Inc.
9db4e0ec
RK
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
a35311b0
RK
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
9db4e0ec
RK
20
21
22/* This program reads the machine description for the compiler target machine
23 and produces a file containing these things:
24
25 1. An array of strings `insn_template' which is indexed by insn code number
26 and contains the template for output of that insn,
27
28 2. An array of functions `insn_outfun' which, indexed by the insn code
29 number, gives the function that returns a template to use for output of
30 that insn. This is used only in the cases where the template is not
31 constant. These cases are specified by a * or @ at the beginning of the
32 template string in the machine description. They are identified for the
33 sake of other parts of the compiler by a zero element in `insn_template'.
34
35 3. An array of functions `insn_gen_function' which, indexed
36 by insn code number, gives the function to generate a body
37 for that pattern, given operands as arguments.
38
39 4. An array of strings `insn_name' which, indexed by insn code number,
40 gives the name for that pattern. Nameless patterns are given a name.
41
42 5. An array of ints `insn_n_operands' which is indexed by insn code number
43 and contains the number of distinct operands in the pattern for that insn,
44
45 6. An array of ints `insn_n_dups' which is indexed by insn code number
46 and contains the number of match_dup's that appear in the insn's pattern.
47 This says how many elements of `recog_dup_loc' are significant
48 after an insn has been recognized.
49
50 7. An array of arrays of operand constraint strings,
51 `insn_operand_constraint',
52 indexed first by insn code number and second by operand number,
53 containing the constraint for that operand.
54
55 This array is generated only if register constraints appear in
56 match_operand rtx's.
57
58 8. An array of arrays of chars which indicate which operands of
59 which insn patterns appear within ADDRESS rtx's. This array is
60 called `insn_operand_address_p' and is generated only if there
61 are *no* register constraints in the match_operand rtx's.
62
63 9. An array of arrays of machine modes, `insn_operand_mode',
64 indexed first by insn code number and second by operand number,
65 containing the machine mode that that operand is supposed to have.
66 Also `insn_operand_strict_low', which is nonzero for operands
67 contained in a STRICT_LOW_PART.
68
69 10. An array of arrays of int-valued functions, `insn_operand_predicate',
70 indexed first by insn code number and second by operand number,
71 containing the match_operand predicate for this operand.
72
73 11. An array of ints, `insn_n_alternatives', that gives the number
74 of alternatives in the constraints of each pattern.
75
76The code number of an insn is simply its position in the machine description;
77code numbers are assigned sequentially to entries in the description,
78starting with code number 0.
79
80Thus, the following entry in the machine description
81
82 (define_insn "clrdf"
83 [(set (match_operand:DF 0 "general_operand" "")
84 (const_int 0))]
85 ""
86 "clrd %0")
87
88assuming it is the 25th entry present, would cause
89insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1.
90It would not make an case in output_insn_hairy because the template
91given in the entry is a constant (it does not start with `*'). */
92\f
20f92396 93#include "hconfig.h"
0b93b64e 94#include "system.h"
9db4e0ec
RK
95#include "rtl.h"
96#include "obstack.h"
97
98/* No instruction can have more operands than this.
99 Sorry for this arbitrary limit, but what machine will
100 have an instruction with this many operands? */
101
102#define MAX_MAX_OPERANDS 40
103
104static struct obstack obstack;
105struct obstack *rtl_obstack = &obstack;
106
107#define obstack_chunk_alloc xmalloc
108#define obstack_chunk_free free
109
2a611d21 110void fatal PVPROTO ((const char *, ...))
bf94d1ec
KG
111 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
112void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
85fda1eb 113static void error PVPROTO ((const char *, ...)) ATTRIBUTE_PRINTF_1;
0b93b64e 114static int n_occurrences PROTO((int, char *));
9db4e0ec 115
4db83042
MM
116/* Define this so we can link with print-rtl.o to get debug_rtx function. */
117char **insn_name_ptr = 0;
118
9db4e0ec
RK
119/* insns in the machine description are assigned sequential code numbers
120 that are used by insn-recog.c (produced by genrecog) to communicate
121 to insn-output.c (produced by this program). */
122
123static int next_code_number;
124
125/* This counts all definitions in the md file,
126 for the sake of error messages. */
127
128static int next_index_number;
129
130/* Record in this chain all information that we will output,
131 associated with the code number of the insn. */
132
133struct data
134{
135 int code_number;
136 int index_number;
137 char *name;
138 char *template; /* string such as "movl %1,%0" */
139 int n_operands; /* Number of operands this insn recognizes */
140 int n_dups; /* Number times match_dup appears in pattern */
141 int n_alternatives; /* Number of alternatives in each constraint */
142 struct data *next;
143 char *constraints[MAX_MAX_OPERANDS];
144 /* Number of alternatives in constraints of operand N. */
145 int op_n_alternatives[MAX_MAX_OPERANDS];
146 char *predicates[MAX_MAX_OPERANDS];
147 char address_p[MAX_MAX_OPERANDS];
148 enum machine_mode modes[MAX_MAX_OPERANDS];
149 char strict_low[MAX_MAX_OPERANDS];
150 char outfun; /* Nonzero means this has an output function */
151};
152
153/* This variable points to the first link in the chain. */
154
155struct data *insn_data;
156
157/* Pointer to the last link in the chain, so new elements
158 can be added at the end. */
159
160struct data *end_of_insn_data;
161
162/* Nonzero if any match_operand has a constraint string;
163 implies that REGISTER_CONSTRAINTS will be defined
164 for this machine description. */
165
166int have_constraints;
6a270722
RK
167
168/* Nonzero if some error has occurred. We will make all errors fatal, but
169 might as well continue until we see all of them. */
170
171static int have_error;
9db4e0ec 172\f
8aeba909 173static char * name_for_index PROTO((int));
56c0e996
BS
174static void output_prologue PROTO((void));
175static void output_epilogue PROTO((void));
176static void scan_operands PROTO((rtx, int, int));
177static void process_template PROTO((struct data *, char *));
178static void validate_insn_alternatives PROTO((struct data *));
179static void gen_insn PROTO((rtx));
180static void gen_peephole PROTO((rtx));
181static void gen_expand PROTO((rtx));
182static void gen_split PROTO((rtx));
183static int n_occurrences PROTO((int, char *));
184\f
8aeba909
RH
185static char *
186name_for_index (index)
187 int index;
188{
189 static char buf[100];
190
191 struct data *i, *last_named = NULL;
192 for (i = insn_data; i ; i = i->next)
193 {
194 if (i->index_number == index)
195 return i->name;
196 if (i->name)
197 last_named = i;
198 }
199
200 if (last_named)
201 sprintf(buf, "%s+%d", last_named->name, index - last_named->index_number);
202 else
203 sprintf(buf, "insn %d", index);
204
205 return buf;
206}
207
9db4e0ec
RK
208static void
209output_prologue ()
210{
9db4e0ec
RK
211 printf ("/* Generated automatically by the program `genoutput'\n\
212from the machine description file `md'. */\n\n");
213
214 printf ("#include \"config.h\"\n");
729da3f5 215 printf ("#include \"system.h\"\n");
ccd043a9 216 printf ("#include \"flags.h\"\n");
9db4e0ec 217 printf ("#include \"rtl.h\"\n");
49ad7cfa 218 printf ("#include \"function.h\"\n");
9db4e0ec
RK
219 printf ("#include \"regs.h\"\n");
220 printf ("#include \"hard-reg-set.h\"\n");
221 printf ("#include \"real.h\"\n");
222 printf ("#include \"insn-config.h\"\n\n");
223 printf ("#include \"conditions.h\"\n");
224 printf ("#include \"insn-flags.h\"\n");
225 printf ("#include \"insn-attr.h\"\n\n");
226 printf ("#include \"insn-codes.h\"\n\n");
227 printf ("#include \"recog.h\"\n\n");
228
9db4e0ec
RK
229 printf ("#include \"output.h\"\n");
230}
231
232static void
233output_epilogue ()
234{
235 register struct data *d;
236
9b3142b3 237 printf ("\nconst char * const insn_template[] =\n {\n");
9db4e0ec
RK
238 for (d = insn_data; d; d = d->next)
239 {
240 if (d->template)
241 printf (" \"%s\",\n", d->template);
242 else
243 printf (" 0,\n");
244 }
245 printf (" };\n");
246
69277eec 247 printf ("\nconst char *(*const insn_outfun[]) PROTO((rtx *, rtx)) =\n {\n");
9db4e0ec
RK
248 for (d = insn_data; d; d = d->next)
249 {
250 if (d->outfun)
251 printf (" output_%d,\n", d->code_number);
252 else
253 printf (" 0,\n");
254 }
255 printf (" };\n");
256
257 printf ("\nrtx (*const insn_gen_function[]) () =\n {\n");
258 for (d = insn_data; d; d = d->next)
259 {
52a1f21f 260 if (d->name && d->name[0] != '*')
9db4e0ec
RK
261 printf (" gen_%s,\n", d->name);
262 else
263 printf (" 0,\n");
264 }
265 printf (" };\n");
266
9b3142b3 267 printf ("\nconst char *insn_name[] =\n {\n");
9db4e0ec
RK
268 {
269 int offset = 0;
270 int next;
271 char * last_name = 0;
9e2d6f95 272 char * next_name = 0;
9db4e0ec
RK
273 register struct data *n;
274
35a3523c 275 for (n = insn_data, next = 1; n; n = n->next, next++)
9db4e0ec
RK
276 if (n->name)
277 {
278 next_name = n->name;
279 break;
280 }
281
282 for (d = insn_data; d; d = d->next)
283 {
284 if (d->name)
285 {
286 printf (" \"%s\",\n", d->name);
287 offset = 0;
288 last_name = d->name;
289 next_name = 0;
290 for (n = d->next, next = 1; n; n = n->next, next++)
291 if (n->name)
292 {
293 next_name = n->name;
294 break;
295 }
296 }
297 else
298 {
299 offset++;
300 if (next_name && (last_name == 0 || offset > next / 2))
301 printf (" \"%s-%d\",\n", next_name, next - offset);
302 else
303 printf (" \"%s+%d\",\n", last_name, offset);
304 }
305 }
306 }
307 printf (" };\n");
9b3142b3 308 printf ("const char **insn_name_ptr = insn_name;\n");
9db4e0ec
RK
309
310 printf ("\nconst int insn_n_operands[] =\n {\n");
311 for (d = insn_data; d; d = d->next)
312 printf (" %d,\n", d->n_operands);
313 printf (" };\n");
314
315 printf ("\nconst int insn_n_dups[] =\n {\n");
316 for (d = insn_data; d; d = d->next)
317 printf (" %d,\n", d->n_dups);
318 printf (" };\n");
319
320 if (have_constraints)
321 {
9b3142b3 322 printf ("\nconst char *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n");
9db4e0ec
RK
323 for (d = insn_data; d; d = d->next)
324 {
325 register int i;
326 printf (" {");
327 for (i = 0; i < d->n_operands; i++)
328 {
329 if (d->constraints[i] == 0)
330 printf (" \"\",");
331 else
332 printf (" \"%s\",", d->constraints[i]);
333 }
334 if (d->n_operands == 0)
335 printf (" 0");
336 printf (" },\n");
337 }
338 printf (" };\n");
339 }
340 else
341 {
342 printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n");
343 for (d = insn_data; d; d = d->next)
344 {
345 register int i;
346 printf (" {");
347 for (i = 0; i < d->n_operands; i++)
348 printf (" %d,", d->address_p[i]);
349 if (d->n_operands == 0)
350 printf (" 0");
351 printf (" },\n");
352 }
353 printf (" };\n");
354 }
355
356 printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n");
357 for (d = insn_data; d; d = d->next)
358 {
359 register int i;
360 printf (" {");
361 for (i = 0; i < d->n_operands; i++)
362 printf (" %smode,", GET_MODE_NAME (d->modes[i]));
363 if (d->n_operands == 0)
364 printf (" VOIDmode");
365 printf (" },\n");
366 }
367 printf (" };\n");
368
369 printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n");
370 for (d = insn_data; d; d = d->next)
371 {
372 register int i;
373 printf (" {");
374 for (i = 0; i < d->n_operands; i++)
375 printf (" %d,", d->strict_low[i]);
376 if (d->n_operands == 0)
377 printf (" 0");
378 printf (" },\n");
379 }
380 printf (" };\n");
381
382 {
383 /* We need to define all predicates used. Keep a list of those we
384 have defined so far. There normally aren't very many predicates used,
385 so a linked list should be fast enough. */
386 struct predicate { char *name; struct predicate *next; } *predicates = 0;
387 struct predicate *p;
388 int i;
389
390 printf ("\n");
391 for (d = insn_data; d; d = d->next)
392 for (i = 0; i < d->n_operands; i++)
393 if (d->predicates[i] && d->predicates[i][0])
394 {
395 for (p = predicates; p; p = p->next)
396 if (! strcmp (p->name, d->predicates[i]))
397 break;
398
399 if (p == 0)
400 {
69277eec
KG
401 printf ("extern int %s PROTO ((rtx, enum machine_mode));\n",
402 d->predicates[i]);
9db4e0ec
RK
403 p = (struct predicate *) alloca (sizeof (struct predicate));
404 p->name = d->predicates[i];
405 p->next = predicates;
406 predicates = p;
407 }
408 }
409
69277eec 410 printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) PROTO ((rtx, enum machine_mode)) =\n {\n");
9db4e0ec
RK
411 for (d = insn_data; d; d = d->next)
412 {
413 printf (" {");
414 for (i = 0; i < d->n_operands; i++)
415 printf (" %s,", ((d->predicates[i] && d->predicates[i][0])
416 ? d->predicates[i] : "0"));
417 if (d->n_operands == 0)
418 printf (" 0");
419 printf (" },\n");
420 }
421 printf (" };\n");
422 }
423
424 printf ("\nconst int insn_n_alternatives[] =\n {\n");
425 for (d = insn_data; d; d = d->next)
426 printf (" %d,\n", d->n_alternatives);
427 printf(" };\n");
428}
429\f
430/* scan_operands (X) stores in max_opno the largest operand
431 number present in X, if that is larger than the previous
432 value of max_opno. It stores all the constraints in `constraints'
433 and all the machine modes in `modes'.
434
435 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
436 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
437
438static int max_opno;
439static int num_dups;
440static char *constraints[MAX_MAX_OPERANDS];
441static int op_n_alternatives[MAX_MAX_OPERANDS];
85fda1eb 442static const char *predicates[MAX_MAX_OPERANDS];
9db4e0ec
RK
443static char address_p[MAX_MAX_OPERANDS];
444static enum machine_mode modes[MAX_MAX_OPERANDS];
445static char strict_low[MAX_MAX_OPERANDS];
5a806d65 446static char seen[MAX_MAX_OPERANDS];
9db4e0ec
RK
447
448static void
449scan_operands (part, this_address_p, this_strict_low)
450 rtx part;
451 int this_address_p;
452 int this_strict_low;
453{
454 register int i, j;
6f7d635c 455 register const char *format_ptr;
9db4e0ec
RK
456 int opno;
457
458 if (part == 0)
459 return;
460
461 switch (GET_CODE (part))
462 {
463 case MATCH_OPERAND:
464 opno = XINT (part, 0);
465 if (opno > max_opno)
466 max_opno = opno;
467 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 468 {
8aeba909
RH
469 error ("Too many operands (%d) in definition %s.\n",
470 max_opno + 1, name_for_index (next_index_number));
5a806d65
RK
471 return;
472 }
473 if (seen[opno])
8aeba909
RH
474 error ("Definition %s specified operand number %d more than once.\n",
475 name_for_index (next_index_number), opno);
5a806d65 476 seen[opno] = 1;
9db4e0ec
RK
477 modes[opno] = GET_MODE (part);
478 strict_low[opno] = this_strict_low;
479 predicates[opno] = XSTR (part, 1);
480 constraints[opno] = XSTR (part, 2);
481 if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0)
482 {
483 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1;
484 have_constraints = 1;
485 }
486 address_p[opno] = this_address_p;
487 return;
488
489 case MATCH_SCRATCH:
490 opno = XINT (part, 0);
491 if (opno > max_opno)
492 max_opno = opno;
493 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 494 {
8aeba909
RH
495 error ("Too many operands (%d) in definition %s.\n",
496 max_opno + 1, name_for_index (next_index_number));
5a806d65
RK
497 return;
498 }
499 if (seen[opno])
8aeba909
RH
500 error ("Definition %s specified operand number %d more than once.\n",
501 name_for_index (next_index_number), opno);
5a806d65 502 seen[opno] = 1;
9db4e0ec
RK
503 modes[opno] = GET_MODE (part);
504 strict_low[opno] = 0;
505 predicates[opno] = "scratch_operand";
506 constraints[opno] = XSTR (part, 1);
507 if (XSTR (part, 1) != 0 && *XSTR (part, 1) != 0)
508 {
509 op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 1)) + 1;
510 have_constraints = 1;
511 }
512 address_p[opno] = 0;
513 return;
514
515 case MATCH_OPERATOR:
516 case MATCH_PARALLEL:
517 opno = XINT (part, 0);
518 if (opno > max_opno)
519 max_opno = opno;
520 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 521 {
8aeba909
RH
522 error ("Too many operands (%d) in definition %s.\n",
523 max_opno + 1, name_for_index (next_index_number));
5a806d65
RK
524 return;
525 }
526 if (seen[opno])
8aeba909
RH
527 error ("Definition %s specified operand number %d more than once.\n",
528 name_for_index (next_index_number), opno);
5a806d65 529 seen[opno] = 1;
9db4e0ec
RK
530 modes[opno] = GET_MODE (part);
531 strict_low[opno] = 0;
532 predicates[opno] = XSTR (part, 1);
533 constraints[opno] = 0;
534 address_p[opno] = 0;
535 for (i = 0; i < XVECLEN (part, 2); i++)
536 scan_operands (XVECEXP (part, 2, i), 0, 0);
537 return;
538
539 case MATCH_DUP:
540 case MATCH_OP_DUP:
ed18f94d 541 case MATCH_PAR_DUP:
9db4e0ec
RK
542 ++num_dups;
543 return;
544
545 case ADDRESS:
546 scan_operands (XEXP (part, 0), 1, 0);
547 return;
548
549 case STRICT_LOW_PART:
550 scan_operands (XEXP (part, 0), 0, 1);
551 return;
ccd043a9
RL
552
553 default:
554 break;
9db4e0ec
RK
555 }
556
557 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
558
559 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
560 switch (*format_ptr++)
561 {
562 case 'e':
ccd043a9 563 case 'u':
9db4e0ec
RK
564 scan_operands (XEXP (part, i), 0, 0);
565 break;
566 case 'E':
567 if (XVEC (part, i) != NULL)
568 for (j = 0; j < XVECLEN (part, i); j++)
569 scan_operands (XVECEXP (part, i, j), 0, 0);
570 break;
571 }
572}
573\f
574/* Process an assembler template from a define_insn or a define_peephole.
575 It is either the assembler code template, a list of assembler code
576 templates, or C code to generate the assembler code template. */
577
578static void
579process_template (d, template)
580 struct data *d;
581 char *template;
582{
583 register char *cp;
584 register int i;
585
586 /* We need to consider only the instructions whose assembler code template
587 starts with a * or @. These are the ones where C code is run to decide
588 on a template to use. So for all others just return now. */
589
590 if (template[0] != '*' && template[0] != '@')
591 {
592 d->template = template;
593 d->outfun = 0;
594 return;
595 }
596
597 d->template = 0;
598 d->outfun = 1;
599
69277eec
KG
600 printf ("\nstatic const char *output_%d PROTO ((rtx *, rtx));\n",
601 d->code_number);
9b3142b3 602 printf ("\nstatic const char *\n");
9db4e0ec 603 printf ("output_%d (operands, insn)\n", d->code_number);
3286ab57
KG
604 printf (" rtx *operands ATTRIBUTE_UNUSED;\n");
605 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
9db4e0ec
RK
606 printf ("{\n");
607
608 /* If the assembler code template starts with a @ it is a newline-separated
609 list of assembler code templates, one for each alternative. So produce
610 a routine to select the correct one. */
611
612 if (template[0] == '@')
613 {
614
9b3142b3 615 printf (" static const char *const strings_%d[] = {\n",
9db4e0ec
RK
616 d->code_number);
617
618 for (i = 0, cp = &template[1]; *cp; )
619 {
620 while (*cp == '\n' || *cp == ' ' || *cp== '\t')
621 cp++;
622
623 printf (" \"");
624 while (*cp != '\n' && *cp != '\0')
2f013c71
RK
625 {
626 putchar (*cp);
627 cp++;
628 }
9db4e0ec
RK
629
630 printf ("\",\n");
631 i++;
632 }
633
634 printf (" };\n");
635 printf (" return strings_%d[which_alternative];\n", d->code_number);
636
637 if (i != d->n_alternatives)
638 fatal ("Insn pattern %d has %d alternatives but %d assembler choices",
639 d->index_number, d->n_alternatives, i);
640
641 }
642 else
643 {
644 /* The following is done in a funny way to get around problems in
645 VAX-11 "C" on VMS. It is the equivalent of:
646 printf ("%s\n", &template[1])); */
647 cp = &template[1];
2f013c71
RK
648 while (*cp)
649 {
650 putchar (*cp);
651 cp++;
652 }
9db4e0ec
RK
653 putchar ('\n');
654 }
655
656 printf ("}\n");
657}
658\f
659/* Check insn D for consistency in number of constraint alternatives. */
660
661static void
662validate_insn_alternatives (d)
663 struct data *d;
664{
665 register int n = 0, start;
666 /* Make sure all the operands have the same number of
667 alternatives in their constraints.
668 Let N be that number. */
669 for (start = 0; start < d->n_operands; start++)
670 if (d->op_n_alternatives[start] > 0)
671 {
672 if (n == 0)
673 n = d->op_n_alternatives[start];
674 else if (n != d->op_n_alternatives[start])
8aeba909
RH
675 error ("wrong number of alternatives in operand %d of insn %s",
676 start, name_for_index (d->index_number));
9db4e0ec
RK
677 }
678 /* Record the insn's overall number of alternatives. */
679 d->n_alternatives = n;
680}
681\f
682/* Look at a define_insn just read. Assign its code number.
683 Record on insn_data the template and the number of arguments.
684 If the insn has a hairy output action, output a function for now. */
685
686static void
687gen_insn (insn)
688 rtx insn;
689{
690 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
691 register int i;
692
693 d->code_number = next_code_number++;
694 d->index_number = next_index_number;
695 if (XSTR (insn, 0)[0])
696 d->name = XSTR (insn, 0);
697 else
698 d->name = 0;
699
700 /* Build up the list in the same order as the insns are seen
701 in the machine description. */
702 d->next = 0;
703 if (end_of_insn_data)
704 end_of_insn_data->next = d;
705 else
706 insn_data = d;
707
708 end_of_insn_data = d;
709
710 max_opno = -1;
711 num_dups = 0;
712
efd59a33
KG
713 memset (constraints, 0, sizeof constraints);
714 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
715 memset (predicates, 0, sizeof predicates);
716 memset (address_p, 0, sizeof address_p);
717 memset (modes, 0, sizeof modes);
718 memset (strict_low, 0, sizeof strict_low);
719 memset (seen, 0, sizeof seen);
9db4e0ec
RK
720
721 for (i = 0; i < XVECLEN (insn, 1); i++)
722 scan_operands (XVECEXP (insn, 1, i), 0, 0);
723
724 d->n_operands = max_opno + 1;
725 d->n_dups = num_dups;
726
efd59a33
KG
727 memcpy (d->constraints, constraints, sizeof constraints);
728 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
729 memcpy (d->predicates, predicates, sizeof predicates);
730 memcpy (d->address_p, address_p, sizeof address_p);
731 memcpy (d->modes, modes, sizeof modes);
732 memcpy (d->strict_low, strict_low, sizeof strict_low);
9db4e0ec
RK
733
734 validate_insn_alternatives (d);
735 process_template (d, XSTR (insn, 3));
736}
737\f
738/* Look at a define_peephole just read. Assign its code number.
739 Record on insn_data the template and the number of arguments.
740 If the insn has a hairy output action, output it now. */
741
742static void
743gen_peephole (peep)
744 rtx peep;
745{
746 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
747 register int i;
748
749 d->code_number = next_code_number++;
750 d->index_number = next_index_number;
751 d->name = 0;
752
753 /* Build up the list in the same order as the insns are seen
754 in the machine description. */
755 d->next = 0;
756 if (end_of_insn_data)
757 end_of_insn_data->next = d;
758 else
759 insn_data = d;
760
761 end_of_insn_data = d;
762
763 max_opno = -1;
efd59a33
KG
764 memset (constraints, 0, sizeof constraints);
765 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
766 memset (predicates, 0, sizeof predicates);
767 memset (address_p, 0, sizeof address_p);
768 memset (modes, 0, sizeof modes);
769 memset (strict_low, 0, sizeof strict_low);
770 memset (seen, 0, sizeof seen);
9db4e0ec
RK
771
772 /* Get the number of operands by scanning all the
773 patterns of the peephole optimizer.
774 But ignore all the rest of the information thus obtained. */
775 for (i = 0; i < XVECLEN (peep, 0); i++)
776 scan_operands (XVECEXP (peep, 0, i), 0, 0);
777
778 d->n_operands = max_opno + 1;
779 d->n_dups = 0;
780
efd59a33
KG
781 memcpy (d->constraints, constraints, sizeof constraints);
782 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
783 memset (d->predicates, 0, sizeof predicates);
784 memset (d->address_p, 0, sizeof address_p);
785 memset (d->modes, 0, sizeof modes);
786 memset (d->strict_low, 0, sizeof strict_low);
9db4e0ec
RK
787
788 validate_insn_alternatives (d);
789 process_template (d, XSTR (peep, 2));
790}
791\f
792/* Process a define_expand just read. Assign its code number,
793 only for the purposes of `insn_gen_function'. */
794
795static void
796gen_expand (insn)
797 rtx insn;
798{
799 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
800 register int i;
801
802 d->code_number = next_code_number++;
803 d->index_number = next_index_number;
804 if (XSTR (insn, 0)[0])
805 d->name = XSTR (insn, 0);
806 else
807 d->name = 0;
808
809 /* Build up the list in the same order as the insns are seen
810 in the machine description. */
811 d->next = 0;
812 if (end_of_insn_data)
813 end_of_insn_data->next = d;
814 else
815 insn_data = d;
816
817 end_of_insn_data = d;
818
819 max_opno = -1;
820 num_dups = 0;
821
822 /* Scan the operands to get the specified predicates and modes,
823 since expand_binop needs to know them. */
824
efd59a33
KG
825 memset (constraints, 0, sizeof constraints);
826 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
827 memset (predicates, 0, sizeof predicates);
828 memset (address_p, 0, sizeof address_p);
829 memset (modes, 0, sizeof modes);
830 memset (strict_low, 0, sizeof strict_low);
831 memset (seen, 0, sizeof seen);
9db4e0ec
RK
832
833 if (XVEC (insn, 1))
834 for (i = 0; i < XVECLEN (insn, 1); i++)
835 scan_operands (XVECEXP (insn, 1, i), 0, 0);
836
837 d->n_operands = max_opno + 1;
838 d->n_dups = num_dups;
839
efd59a33
KG
840 memcpy (d->constraints, constraints, sizeof constraints);
841 memcpy (d->op_n_alternatives, op_n_alternatives, sizeof op_n_alternatives);
842 memcpy (d->predicates, predicates, sizeof predicates);
843 memcpy (d->address_p, address_p, sizeof address_p);
844 memcpy (d->modes, modes, sizeof modes);
845 memcpy (d->strict_low, strict_low, sizeof strict_low);
9db4e0ec
RK
846
847 d->template = 0;
848 d->outfun = 0;
849 validate_insn_alternatives (d);
850}
851\f
852/* Process a define_split just read. Assign its code number,
853 only for reasons of consistency and to simplify genrecog. */
854
855
856static void
857gen_split (split)
858 rtx split;
859{
860 register struct data *d = (struct data *) xmalloc (sizeof (struct data));
861 register int i;
862
863 d->code_number = next_code_number++;
864 d->index_number = next_index_number;
865 d->name = 0;
866
867 /* Build up the list in the same order as the insns are seen
868 in the machine description. */
869 d->next = 0;
870 if (end_of_insn_data)
871 end_of_insn_data->next = d;
872 else
873 insn_data = d;
874
875 end_of_insn_data = d;
876
877 max_opno = -1;
878 num_dups = 0;
879
efd59a33
KG
880 memset (constraints, 0, sizeof constraints);
881 memset (op_n_alternatives, 0, sizeof op_n_alternatives);
882 memset (predicates, 0, sizeof predicates);
883 memset (address_p, 0, sizeof address_p);
884 memset (modes, 0, sizeof modes);
885 memset (strict_low, 0, sizeof strict_low);
886 memset (seen, 0, sizeof seen);
9db4e0ec
RK
887
888 /* Get the number of operands by scanning all the
889 patterns of the split patterns.
890 But ignore all the rest of the information thus obtained. */
891 for (i = 0; i < XVECLEN (split, 0); i++)
892 scan_operands (XVECEXP (split, 0, i), 0, 0);
893
894 d->n_operands = max_opno + 1;
895
efd59a33
KG
896 memset (d->constraints, 0, sizeof constraints);
897 memset (d->op_n_alternatives, 0, sizeof op_n_alternatives);
898 memset (d->predicates, 0, sizeof predicates);
899 memset (d->address_p, 0, sizeof address_p);
900 memset (d->modes, 0, sizeof modes);
901 memset (d->strict_low, 0, sizeof strict_low);
9db4e0ec
RK
902
903 d->n_dups = 0;
42495ca0 904 d->n_alternatives = 0;
9db4e0ec
RK
905 d->template = 0;
906 d->outfun = 0;
907}
908\f
2778b98d 909PTR
9db4e0ec 910xmalloc (size)
2778b98d 911 size_t size;
9db4e0ec 912{
2778b98d 913 register PTR val = (PTR) malloc (size);
9db4e0ec
RK
914
915 if (val == 0)
916 fatal ("virtual memory exhausted");
917 return val;
918}
919
2778b98d 920PTR
470b68c0
RH
921xrealloc (old, size)
922 PTR old;
2778b98d 923 size_t size;
9db4e0ec 924{
470b68c0 925 register PTR ptr;
09d83d25 926 if (old)
470b68c0
RH
927 ptr = (PTR) realloc (old, size);
928 else
929 ptr = (PTR) malloc (size);
930 if (!ptr)
9db4e0ec 931 fatal ("virtual memory exhausted");
470b68c0 932 return ptr;
9db4e0ec
RK
933}
934
2a611d21 935void
85fda1eb 936fatal VPROTO ((const char *format, ...))
9db4e0ec 937{
5148a72b 938#ifndef ANSI_PROTOTYPES
85fda1eb 939 const char *format;
320e7c40
KG
940#endif
941 va_list ap;
942
943 VA_START (ap, format);
944
5148a72b 945#ifndef ANSI_PROTOTYPES
85fda1eb 946 format = va_arg (ap, const char *);
320e7c40
KG
947#endif
948
9db4e0ec 949 fprintf (stderr, "genoutput: ");
320e7c40
KG
950 vfprintf (stderr, format, ap);
951 va_end (ap);
9db4e0ec
RK
952 fprintf (stderr, "\n");
953 exit (FATAL_EXIT_CODE);
954}
955
956/* More 'friendly' abort that prints the line and file.
957 config.h can #define abort fancy_abort if you like that sort of thing. */
958
959void
960fancy_abort ()
961{
962 fatal ("Internal gcc abort.");
963}
964
965static void
85fda1eb 966error VPROTO ((const char *format, ...))
9db4e0ec 967{
5148a72b 968#ifndef ANSI_PROTOTYPES
85fda1eb 969 const char *format;
320e7c40
KG
970#endif
971 va_list ap;
972
973 VA_START (ap, format);
974
5148a72b 975#ifndef ANSI_PROTOTYPES
85fda1eb 976 format = va_arg (ap, const char *);
320e7c40
KG
977#endif
978
9db4e0ec 979 fprintf (stderr, "genoutput: ");
320e7c40
KG
980 vfprintf (stderr, format, ap);
981 va_end (ap);
9db4e0ec 982 fprintf (stderr, "\n");
6a270722
RK
983
984 have_error = 1;
9db4e0ec
RK
985}
986\f
987int
988main (argc, argv)
989 int argc;
990 char **argv;
991{
992 rtx desc;
993 FILE *infile;
9db4e0ec
RK
994 register int c;
995
996 obstack_init (rtl_obstack);
997
998 if (argc <= 1)
999 fatal ("No input file name.");
1000
1001 infile = fopen (argv[1], "r");
1002 if (infile == 0)
1003 {
1004 perror (argv[1]);
1005 exit (FATAL_EXIT_CODE);
1006 }
1007
1008 init_rtl ();
1009
1010 output_prologue ();
1011 next_code_number = 0;
1012 next_index_number = 0;
1013 have_constraints = 0;
1014
1015 /* Read the machine description. */
1016
1017 while (1)
1018 {
1019 c = read_skip_spaces (infile);
1020 if (c == EOF)
1021 break;
1022 ungetc (c, infile);
1023
1024 desc = read_rtx (infile);
1025 if (GET_CODE (desc) == DEFINE_INSN)
1026 gen_insn (desc);
1027 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
1028 gen_peephole (desc);
1029 if (GET_CODE (desc) == DEFINE_EXPAND)
1030 gen_expand (desc);
1031 if (GET_CODE (desc) == DEFINE_SPLIT)
1032 gen_split (desc);
1033 next_index_number++;
1034 }
1035
1036 output_epilogue ();
1037
1038 fflush (stdout);
6a270722
RK
1039 exit (ferror (stdout) != 0 || have_error
1040 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
1041
9db4e0ec
RK
1042 /* NOTREACHED */
1043 return 0;
1044}
1045
1046static int
1047n_occurrences (c, s)
d149d5f5 1048 int c;
9db4e0ec
RK
1049 char *s;
1050{
1051 int n = 0;
1052 while (*s)
1053 n += (*s++ == c);
1054 return n;
1055}
This page took 0.760133 seconds and 5 git commands to generate.