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