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