]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genoutput.c
sh.h (EXTRA_CONSTRAINT_Z): New macro.
[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 {
6b8b9d7b
CM
369 if (IS_VSPACE (*p) && prev != '\\')
370 {
371 /* Preserve two consecutive \n's or \r's, but treat \r\n
372 as a single newline. */
373 if (*p == '\n' && prev != '\r')
374 printf ("\\n\\\n");
375 }
212d447c
DC
376 else
377 putchar (*p);
378 prev = *p;
379 ++p;
380 }
381 printf ("\",\n");
382 }
4bbf910e
RH
383 break;
384 case INSN_OUTPUT_FORMAT_MULTI:
385 case INSN_OUTPUT_FORMAT_FUNCTION:
4a71b24f 386 printf (" (const PTR) output_%d,\n", d->code_number);
4bbf910e
RH
387 break;
388 default:
389 abort ();
390 }
a995e389
RH
391
392 if (d->name && d->name[0] != '*')
706b0f60 393 printf (" (insn_gen_fn) gen_%s,\n", d->name);
a995e389
RH
394 else
395 printf (" 0,\n");
396
397 printf (" &operand_data[%d],\n", d->operand_number);
398 printf (" %d,\n", d->n_operands);
399 printf (" %d,\n", d->n_dups);
4bbf910e
RH
400 printf (" %d,\n", d->n_alternatives);
401 printf (" %d\n", d->output_format);
a995e389
RH
402
403 printf(" },\n");
9db4e0ec 404 }
a995e389
RH
405 printf ("};\n\n\n");
406}
9db4e0ec 407
a995e389
RH
408static void
409output_get_insn_name ()
410{
411 printf ("const char *\n");
412 printf ("get_insn_name (code)\n");
413 printf (" int code;\n");
414 printf ("{\n");
415 printf (" return insn_data[code].name;\n");
416 printf ("}\n");
9db4e0ec 417}
a995e389 418
9db4e0ec 419\f
a995e389
RH
420/* Stores in max_opno the largest operand number present in `part', if
421 that is larger than the previous value of max_opno, and the rest of
422 the operand data into `d->operand[i]'.
9db4e0ec
RK
423
424 THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS.
425 THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
426
427static int max_opno;
428static int num_dups;
9db4e0ec
RK
429
430static void
a995e389
RH
431scan_operands (d, part, this_address_p, this_strict_low)
432 struct data *d;
9db4e0ec
RK
433 rtx part;
434 int this_address_p;
435 int this_strict_low;
436{
b3694847
SS
437 int i, j;
438 const char *format_ptr;
9db4e0ec
RK
439 int opno;
440
441 if (part == 0)
442 return;
443
444 switch (GET_CODE (part))
445 {
446 case MATCH_OPERAND:
447 opno = XINT (part, 0);
448 if (opno > max_opno)
449 max_opno = opno;
450 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 451 {
d96a2fcd
RH
452 message_with_line (d->lineno,
453 "maximum number of operands exceeded");
454 have_error = 1;
5a806d65
RK
455 return;
456 }
a995e389 457 if (d->operand[opno].seen)
d96a2fcd
RH
458 {
459 message_with_line (d->lineno,
460 "repeated operand number %d\n", opno);
461 have_error = 1;
462 }
463
a995e389
RH
464 d->operand[opno].seen = 1;
465 d->operand[opno].mode = GET_MODE (part);
466 d->operand[opno].strict_low = this_strict_low;
467 d->operand[opno].predicate = XSTR (part, 1);
665f2503
RK
468 d->operand[opno].constraint = strip_whitespace (XSTR (part, 2));
469 d->operand[opno].n_alternatives
470 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 471 d->operand[opno].address_p = this_address_p;
dfac187e 472 d->operand[opno].eliminable = 1;
9db4e0ec
RK
473 return;
474
475 case MATCH_SCRATCH:
476 opno = XINT (part, 0);
477 if (opno > max_opno)
478 max_opno = opno;
479 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 480 {
d96a2fcd
RH
481 message_with_line (d->lineno,
482 "maximum number of operands exceeded");
483 have_error = 1;
5a806d65
RK
484 return;
485 }
a995e389 486 if (d->operand[opno].seen)
d96a2fcd
RH
487 {
488 message_with_line (d->lineno,
489 "repeated operand number %d\n", opno);
490 have_error = 1;
491 }
492
a995e389
RH
493 d->operand[opno].seen = 1;
494 d->operand[opno].mode = GET_MODE (part);
495 d->operand[opno].strict_low = 0;
496 d->operand[opno].predicate = "scratch_operand";
665f2503
RK
497 d->operand[opno].constraint = strip_whitespace (XSTR (part, 1));
498 d->operand[opno].n_alternatives
499 = n_occurrences (',', d->operand[opno].constraint) + 1;
a995e389 500 d->operand[opno].address_p = 0;
dfac187e 501 d->operand[opno].eliminable = 0;
9db4e0ec
RK
502 return;
503
504 case MATCH_OPERATOR:
505 case MATCH_PARALLEL:
506 opno = XINT (part, 0);
507 if (opno > max_opno)
508 max_opno = opno;
509 if (max_opno >= MAX_MAX_OPERANDS)
5a806d65 510 {
d96a2fcd
RH
511 message_with_line (d->lineno,
512 "maximum number of operands exceeded");
513 have_error = 1;
5a806d65
RK
514 return;
515 }
a995e389 516 if (d->operand[opno].seen)
d96a2fcd
RH
517 {
518 message_with_line (d->lineno,
519 "repeated operand number %d\n", opno);
520 have_error = 1;
521 }
522
a995e389
RH
523 d->operand[opno].seen = 1;
524 d->operand[opno].mode = GET_MODE (part);
525 d->operand[opno].strict_low = 0;
526 d->operand[opno].predicate = XSTR (part, 1);
527 d->operand[opno].constraint = 0;
528 d->operand[opno].address_p = 0;
dfac187e 529 d->operand[opno].eliminable = 0;
9db4e0ec 530 for (i = 0; i < XVECLEN (part, 2); i++)
a995e389 531 scan_operands (d, XVECEXP (part, 2, i), 0, 0);
9db4e0ec
RK
532 return;
533
534 case MATCH_DUP:
535 case MATCH_OP_DUP:
ed18f94d 536 case MATCH_PAR_DUP:
9db4e0ec 537 ++num_dups;
6d7a1c4c 538 break;
9db4e0ec
RK
539
540 case ADDRESS:
a995e389 541 scan_operands (d, XEXP (part, 0), 1, 0);
9db4e0ec
RK
542 return;
543
544 case STRICT_LOW_PART:
a995e389 545 scan_operands (d, XEXP (part, 0), 0, 1);
9db4e0ec 546 return;
ccd043a9
RL
547
548 default:
549 break;
9db4e0ec
RK
550 }
551
552 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
553
554 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
555 switch (*format_ptr++)
556 {
557 case 'e':
ccd043a9 558 case 'u':
a995e389 559 scan_operands (d, XEXP (part, i), 0, 0);
9db4e0ec
RK
560 break;
561 case 'E':
562 if (XVEC (part, i) != NULL)
563 for (j = 0; j < XVECLEN (part, i); j++)
a995e389 564 scan_operands (d, XVECEXP (part, i, j), 0, 0);
9db4e0ec
RK
565 break;
566 }
567}
a995e389
RH
568
569/* Compare two operands for content equality. */
570
571static int
572compare_operands (d0, d1)
573 struct operand_data *d0, *d1;
574{
c1b59dce 575 const char *p0, *p1;
a995e389
RH
576
577 p0 = d0->predicate;
578 if (!p0)
579 p0 = "";
580 p1 = d1->predicate;
581 if (!p1)
582 p1 = "";
583 if (strcmp (p0, p1) != 0)
584 return 0;
585
19af6455
BS
586 p0 = d0->constraint;
587 if (!p0)
588 p0 = "";
589 p1 = d1->constraint;
590 if (!p1)
591 p1 = "";
592 if (strcmp (p0, p1) != 0)
593 return 0;
a995e389
RH
594
595 if (d0->mode != d1->mode)
596 return 0;
597
a995e389
RH
598 if (d0->strict_low != d1->strict_low)
599 return 0;
600
dfac187e
BS
601 if (d0->eliminable != d1->eliminable)
602 return 0;
603
a995e389
RH
604 return 1;
605}
606
607/* Scan the list of operands we've already committed to output and either
608 find a subsequence that is the same, or allocate a new one at the end. */
609
610static void
611place_operands (d)
612 struct data *d;
613{
614 struct operand_data *od, *od2;
615 int i;
616
617 if (d->n_operands == 0)
618 {
619 d->operand_number = 0;
620 return;
621 }
622
623 /* Brute force substring search. */
624 for (od = odata, i = 0; od; od = od->next, i = 0)
625 if (compare_operands (od, &d->operand[0]))
626 {
627 od2 = od->next;
628 i = 1;
629 while (1)
630 {
631 if (i == d->n_operands)
632 goto full_match;
633 if (od2 == NULL)
634 goto partial_match;
635 if (! compare_operands (od2, &d->operand[i]))
636 break;
637 ++i, od2 = od2->next;
638 }
639 }
640
641 /* Either partial match at the end of the list, or no match. In either
642 case, we tack on what operands are remaining to the end of the list. */
643 partial_match:
644 d->operand_number = next_operand_number - i;
645 for (; i < d->n_operands; ++i)
646 {
647 od2 = &d->operand[i];
648 *odata_end = od2;
649 odata_end = &od2->next;
650 od2->index = next_operand_number++;
651 }
652 *odata_end = NULL;
653 return;
654
655 full_match:
656 d->operand_number = od->index;
657 return;
658}
659
9db4e0ec
RK
660\f
661/* Process an assembler template from a define_insn or a define_peephole.
662 It is either the assembler code template, a list of assembler code
663 templates, or C code to generate the assembler code template. */
664
665static void
666process_template (d, template)
667 struct data *d;
3cce094d 668 const char *template;
9db4e0ec 669{
b3694847
SS
670 const char *cp;
671 int i;
9db4e0ec 672
4bbf910e
RH
673 /* Templates starting with * contain straight code to be run. */
674 if (template[0] == '*')
9db4e0ec 675 {
4bbf910e
RH
676 d->template = 0;
677 d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
9db4e0ec 678
a94ae8f5 679 printf ("\nstatic const char *output_%d PARAMS ((rtx *, rtx));\n",
4bbf910e
RH
680 d->code_number);
681 puts ("\nstatic const char *");
682 printf ("output_%d (operands, insn)\n", d->code_number);
683 puts (" rtx *operands ATTRIBUTE_UNUSED;");
684 puts (" rtx insn ATTRIBUTE_UNUSED;");
685 puts ("{");
686
687 puts (template + 1);
688 puts ("}");
689 }
9db4e0ec
RK
690
691 /* If the assembler code template starts with a @ it is a newline-separated
4bbf910e
RH
692 list of assembler code templates, one for each alternative. */
693 else if (template[0] == '@')
9db4e0ec 694 {
4bbf910e
RH
695 d->template = 0;
696 d->output_format = INSN_OUTPUT_FORMAT_MULTI;
9db4e0ec 697
4bbf910e 698 printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
9db4e0ec
RK
699
700 for (i = 0, cp = &template[1]; *cp; )
701 {
6b8b9d7b 702 while (ISSPACE (*cp))
9db4e0ec
RK
703 cp++;
704
4bbf910e 705 printf (" \"");
6b8b9d7b 706 while (!IS_VSPACE (*cp) && *cp != '\0')
2f013c71
RK
707 {
708 putchar (*cp);
709 cp++;
710 }
9db4e0ec
RK
711
712 printf ("\",\n");
713 i++;
714 }
c6d79bee
JH
715 if (i == 1)
716 message_with_line (d->lineno,
717 "'@' is redundant for output template with single alternative");
718 if (i != d->n_alternatives)
719 {
720 message_with_line (d->lineno,
1f978f5f 721 "wrong number of alternatives in the output template");
c6d79bee
JH
722 have_error = 1;
723 }
9db4e0ec 724
4bbf910e 725 printf ("};\n");
9db4e0ec
RK
726 }
727 else
728 {
4bbf910e
RH
729 d->template = template;
730 d->output_format = INSN_OUTPUT_FORMAT_SINGLE;
9db4e0ec 731 }
9db4e0ec
RK
732}
733\f
734/* Check insn D for consistency in number of constraint alternatives. */
735
736static void
737validate_insn_alternatives (d)
738 struct data *d;
739{
b3694847 740 int n = 0, start;
a995e389
RH
741
742 /* Make sure all the operands have the same number of alternatives
743 in their constraints. Let N be that number. */
9db4e0ec 744 for (start = 0; start < d->n_operands; start++)
a995e389 745 if (d->operand[start].n_alternatives > 0)
9db4e0ec
RK
746 {
747 if (n == 0)
a995e389
RH
748 n = d->operand[start].n_alternatives;
749 else if (n != d->operand[start].n_alternatives)
d96a2fcd
RH
750 {
751 message_with_line (d->lineno,
752 "wrong number of alternatives in operand %d",
753 start);
754 have_error = 1;
755 }
9db4e0ec 756 }
a995e389 757
9db4e0ec
RK
758 /* Record the insn's overall number of alternatives. */
759 d->n_alternatives = n;
760}
c77e04ae
RH
761
762/* Verify that there are no gaps in operand numbers for INSNs. */
763
764static void
765validate_insn_operands (d)
766 struct data *d;
767{
768 int i;
769
770 for (i = 0; i < d->n_operands; ++i)
771 if (d->operand[i].seen == 0)
772 {
773 message_with_line (d->lineno, "missing operand %d", i);
774 have_error = 1;
775 }
776}
9db4e0ec 777\f
a995e389
RH
778/* Look at a define_insn just read. Assign its code number. Record
779 on idata the template and the number of arguments. If the insn has
780 a hairy output action, output a function for now. */
9db4e0ec
RK
781
782static void
d96a2fcd 783gen_insn (insn, lineno)
9db4e0ec 784 rtx insn;
d96a2fcd 785 int lineno;
9db4e0ec 786{
b3694847
SS
787 struct data *d = (struct data *) xmalloc (sizeof (struct data));
788 int i;
9db4e0ec 789
c88c0d42 790 d->code_number = next_code_number;
9db4e0ec 791 d->index_number = next_index_number;
d96a2fcd 792 d->lineno = lineno;
9db4e0ec
RK
793 if (XSTR (insn, 0)[0])
794 d->name = XSTR (insn, 0);
795 else
796 d->name = 0;
797
798 /* Build up the list in the same order as the insns are seen
799 in the machine description. */
800 d->next = 0;
a995e389
RH
801 *idata_end = d;
802 idata_end = &d->next;
9db4e0ec
RK
803
804 max_opno = -1;
805 num_dups = 0;
a995e389 806 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
807
808 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 809 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
810
811 d->n_operands = max_opno + 1;
812 d->n_dups = num_dups;
813
c77e04ae 814 validate_insn_operands (d);
9db4e0ec 815 validate_insn_alternatives (d);
a995e389 816 place_operands (d);
1f3b37a3 817 process_template (d, XTMPL (insn, 3));
9db4e0ec
RK
818}
819\f
820/* Look at a define_peephole just read. Assign its code number.
a995e389 821 Record on idata the template and the number of arguments.
9db4e0ec
RK
822 If the insn has a hairy output action, output it now. */
823
824static void
d96a2fcd 825gen_peephole (peep, lineno)
9db4e0ec 826 rtx peep;
d96a2fcd 827 int lineno;
9db4e0ec 828{
b3694847
SS
829 struct data *d = (struct data *) xmalloc (sizeof (struct data));
830 int i;
9db4e0ec 831
c88c0d42 832 d->code_number = next_code_number;
9db4e0ec 833 d->index_number = next_index_number;
d96a2fcd 834 d->lineno = lineno;
9db4e0ec
RK
835 d->name = 0;
836
837 /* Build up the list in the same order as the insns are seen
838 in the machine description. */
839 d->next = 0;
a995e389
RH
840 *idata_end = d;
841 idata_end = &d->next;
9db4e0ec
RK
842
843 max_opno = -1;
a995e389
RH
844 num_dups = 0;
845 memset (d->operand, 0, sizeof (d->operand));
846
847 /* Get the number of operands by scanning all the patterns of the
848 peephole optimizer. But ignore all the rest of the information
849 thus obtained. */
9db4e0ec 850 for (i = 0; i < XVECLEN (peep, 0); i++)
a995e389 851 scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
9db4e0ec
RK
852
853 d->n_operands = max_opno + 1;
854 d->n_dups = 0;
855
9db4e0ec 856 validate_insn_alternatives (d);
a995e389 857 place_operands (d);
1f3b37a3 858 process_template (d, XTMPL (peep, 2));
9db4e0ec
RK
859}
860\f
861/* Process a define_expand just read. Assign its code number,
862 only for the purposes of `insn_gen_function'. */
863
864static void
d96a2fcd 865gen_expand (insn, lineno)
9db4e0ec 866 rtx insn;
d96a2fcd 867 int lineno;
9db4e0ec 868{
b3694847
SS
869 struct data *d = (struct data *) xmalloc (sizeof (struct data));
870 int i;
9db4e0ec 871
c88c0d42 872 d->code_number = next_code_number;
9db4e0ec 873 d->index_number = next_index_number;
d96a2fcd 874 d->lineno = lineno;
9db4e0ec
RK
875 if (XSTR (insn, 0)[0])
876 d->name = XSTR (insn, 0);
877 else
878 d->name = 0;
879
880 /* Build up the list in the same order as the insns are seen
881 in the machine description. */
882 d->next = 0;
a995e389
RH
883 *idata_end = d;
884 idata_end = &d->next;
9db4e0ec
RK
885
886 max_opno = -1;
887 num_dups = 0;
a995e389 888 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec
RK
889
890 /* Scan the operands to get the specified predicates and modes,
891 since expand_binop needs to know them. */
892
9db4e0ec
RK
893 if (XVEC (insn, 1))
894 for (i = 0; i < XVECLEN (insn, 1); i++)
a995e389 895 scan_operands (d, XVECEXP (insn, 1, i), 0, 0);
9db4e0ec
RK
896
897 d->n_operands = max_opno + 1;
898 d->n_dups = num_dups;
9db4e0ec 899 d->template = 0;
4bbf910e 900 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389 901
9db4e0ec 902 validate_insn_alternatives (d);
a995e389 903 place_operands (d);
9db4e0ec
RK
904}
905\f
906/* Process a define_split just read. Assign its code number,
907 only for reasons of consistency and to simplify genrecog. */
908
9db4e0ec 909static void
d96a2fcd 910gen_split (split, lineno)
9db4e0ec 911 rtx split;
d96a2fcd 912 int lineno;
9db4e0ec 913{
b3694847
SS
914 struct data *d = (struct data *) xmalloc (sizeof (struct data));
915 int i;
9db4e0ec 916
c88c0d42 917 d->code_number = next_code_number;
9db4e0ec 918 d->index_number = next_index_number;
d96a2fcd 919 d->lineno = lineno;
9db4e0ec
RK
920 d->name = 0;
921
922 /* Build up the list in the same order as the insns are seen
923 in the machine description. */
924 d->next = 0;
a995e389
RH
925 *idata_end = d;
926 idata_end = &d->next;
9db4e0ec
RK
927
928 max_opno = -1;
929 num_dups = 0;
a995e389 930 memset (d->operand, 0, sizeof (d->operand));
9db4e0ec 931
a995e389
RH
932 /* Get the number of operands by scanning all the patterns of the
933 split patterns. But ignore all the rest of the information thus
934 obtained. */
9db4e0ec 935 for (i = 0; i < XVECLEN (split, 0); i++)
a995e389 936 scan_operands (d, XVECEXP (split, 0, i), 0, 0);
9db4e0ec
RK
937
938 d->n_operands = max_opno + 1;
9db4e0ec 939 d->n_dups = 0;
42495ca0 940 d->n_alternatives = 0;
9db4e0ec 941 d->template = 0;
4bbf910e 942 d->output_format = INSN_OUTPUT_FORMAT_NONE;
a995e389
RH
943
944 place_operands (d);
9db4e0ec 945}
9db4e0ec 946
a94ae8f5 947extern int main PARAMS ((int, char **));
c1b59dce 948
9db4e0ec
RK
949int
950main (argc, argv)
951 int argc;
952 char **argv;
953{
954 rtx desc;
9db4e0ec 955
d80eb1e1
RH
956 progname = "genoutput";
957
9db4e0ec 958 if (argc <= 1)
1f978f5f 959 fatal ("no input file name");
9db4e0ec 960
04d8aa70 961 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
c88c0d42 962 return (FATAL_EXIT_CODE);
9db4e0ec 963
9db4e0ec
RK
964 output_prologue ();
965 next_code_number = 0;
966 next_index_number = 0;
9db4e0ec
RK
967
968 /* Read the machine description. */
969
970 while (1)
971 {
c88c0d42
CP
972 int line_no;
973
974 desc = read_md_rtx (&line_no, &next_code_number);
975 if (desc == NULL)
9db4e0ec 976 break;
9db4e0ec 977
9db4e0ec 978 if (GET_CODE (desc) == DEFINE_INSN)
d96a2fcd 979 gen_insn (desc, line_no);
9db4e0ec 980 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
d96a2fcd 981 gen_peephole (desc, line_no);
9db4e0ec 982 if (GET_CODE (desc) == DEFINE_EXPAND)
d96a2fcd 983 gen_expand (desc, line_no);
ede7cd44
RH
984 if (GET_CODE (desc) == DEFINE_SPLIT
985 || GET_CODE (desc) == DEFINE_PEEPHOLE2)
d96a2fcd 986 gen_split (desc, line_no);
9db4e0ec
RK
987 next_index_number++;
988 }
989
a995e389
RH
990 printf("\n\n");
991 output_predicate_decls ();
992 output_operand_data ();
993 output_insn_data ();
994 output_get_insn_name ();
9db4e0ec
RK
995
996 fflush (stdout);
c1b59dce 997 return (ferror (stdout) != 0 || have_error
6a270722 998 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
9db4e0ec
RK
999}
1000
665f2503
RK
1001/* Return the number of occurrences of character C in string S or
1002 -1 if S is the null string. */
1003
9db4e0ec
RK
1004static int
1005n_occurrences (c, s)
d149d5f5 1006 int c;
3cce094d 1007 const char *s;
9db4e0ec
RK
1008{
1009 int n = 0;
665f2503
RK
1010
1011 if (s == 0 || *s == '\0')
1012 return -1;
1013
9db4e0ec
RK
1014 while (*s)
1015 n += (*s++ == c);
665f2503 1016
9db4e0ec
RK
1017 return n;
1018}
88a56c2e 1019
665f2503
RK
1020/* Remove whitespace in `s' by moving up characters until the end.
1021 Return a new string. */
1022
1023static const char *
88a56c2e 1024strip_whitespace (s)
665f2503 1025 const char *s;
88a56c2e 1026{
665f2503
RK
1027 char *p, *q;
1028 char ch;
1029
1030 if (s == 0)
1031 return 0;
88a56c2e 1032
665f2503 1033 p = q = xmalloc (strlen (s) + 1);
88a56c2e
HPN
1034 while ((ch = *s++) != '\0')
1035 if (! ISSPACE (ch))
1036 *p++ = ch;
1037
1038 *p = '\0';
665f2503 1039 return q;
88a56c2e 1040}