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