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