|
|
1.1 root 1: /* Generate code from to output assembler insns as recognized from rtl. 1.1.1.7 ! root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 1.1.1.7 ! root 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 1, or (at your option) ! 9: any later version. ! 10: 1.1 root 11: GNU CC is distributed in the hope that it will be useful, 1.1.1.7 ! root 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 1.1 root 19: 20: 21: /* This program reads the machine description for the compiler target machine 22: and produces a file containing three things: 23: 24: 1, An array of strings `insn_template' which is indexed by insn code number 25: and contains the template for output of that insn, 26: 27: 2. An array of ints `insn_n_operands' which is indexed by insn code number 28: and contains the number of distinct operands in the pattern for that insn, 29: 30: 3. An array of ints `insn_n_dups' which is indexed by insn code number 31: and contains the number of match_dup's that appear in the insn's pattern. 32: This says how many elements of `recog_dup_loc' are significant 33: after an insn has been recognized. 34: 1.1.1.2 root 35: 4. An array of arrays of operand constraint strings, 1.1 root 36: `insn_operand_constraint', 37: indexed first by insn code number and second by operand number, 38: containing the constraint for that operand. 1.1.1.2 root 39: 1.1 root 40: This array is generated only if register constraints appear in 41: match_operand rtx's. 42: 1.1.1.2 root 43: 5. An array of arrays of chars which indicate which operands of 1.1 root 44: which insn patterns appear within ADDRESS rtx's. This array is 45: called `insn_operand_address_p' and is generated only if there 46: are *no* register constraints in the match_operand rtx's. 47: 1.1.1.2 root 48: 6. An array of arrays of machine modes, `insn_operand_mode', 49: indexed first by insn code number and second by operand number, 50: containing the machine mode that that operand is supposed to have. 51: Also `insn_operand_strict_low', which is nonzero for operands 52: contained in a STRICT_LOW_PART. 53: 54: 7. An array of arrays of int-valued functions, `insn_operand_predicate', 55: indexed first by insn code number and second by operand number, 56: containing the match_operand predicate for this operand. 57: 58: 8. An array of functions `insn_gen_function' which, indexed 1.1 root 59: by insn code number, gives the function to generate a body 60: for that patter, given operands as arguments. 61: 1.1.1.2 root 62: 9. A function `output_insn_hairy' which is called with two arguments 1.1 root 63: (an insn code number and a vector of operand value rtx's) 64: and returns a template to use for output of that insn. 65: This is used only in the cases where the template is not constant. 66: These cases are specified by a * at the beginning of the template string 67: in the machine description. They are identified for the sake of 68: other parts of the compiler by a zero element in `insn_template'. 1.1.1.4 root 69: 70: 10. An array of structures, `insn_machine_info', that gives machine-specific 71: information about the insn. 1.1 root 72: 1.1.1.5 root 73: 11. An array of ints, `insn_n_alternatives', that gives the number 74: of alternatives in the constraints of each pattern. 75: 1.1 root 76: The code number of an insn is simply its position in the machine description; 77: code numbers are assigned sequentially to entries in the description, 78: starting with code number 0. 79: 80: Thus, 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: 88: assuming it is the 25th entry present, would cause 1.1.1.2 root 89: insn_template[24] to be "clrd %0", and insn_n_operands[24] to be 1. 1.1 root 90: It would not make an case in output_insn_hairy because the template 91: given in the entry is a constant (it does not start with `*'). */ 92: 93: #include <stdio.h> 1.1.1.2 root 94: #include "config.h" 1.1 root 95: #include "rtl.h" 1.1.1.2 root 96: #include "obstack.h" 1.1 root 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: 104: struct obstack obstack; 1.1.1.2 root 105: struct obstack *rtl_obstack = &obstack; 1.1 root 106: 107: #define obstack_chunk_alloc xmalloc 108: #define obstack_chunk_free free 109: extern int xmalloc (); 110: extern void free (); 111: 112: void fatal (); 1.1.1.6 root 113: void error (); 1.1.1.2 root 114: void mybcopy (); 115: void mybzero (); 1.1 root 116: 117: /* insns in the machine description are assigned sequential code numbers 118: that are used by insn-recog.c (produced by genrecog) to communicate 119: to insn-output.c (produced by this program). */ 120: 121: int next_code_number; 122: 123: /* Record in this chain all information that we will output, 124: associated with the code number of the insn. */ 125: 126: struct data 127: { 128: int code_number; 129: char *name; 130: char *template; /* string such as "movl %1,%0" */ 131: int n_operands; /* Number of operands this insn recognizes */ 132: int n_dups; /* Number times match_dup appears in pattern */ 1.1.1.5 root 133: int n_alternatives; /* Number of alternatives in each constraint */ 1.1 root 134: struct data *next; 135: char *constraints[MAX_MAX_OPERANDS]; 1.1.1.5 root 136: /* Number of alternatives in constraints of operand N. */ 137: int op_n_alternatives[MAX_MAX_OPERANDS]; 1.1.1.2 root 138: char *predicates[MAX_MAX_OPERANDS]; 1.1 root 139: char address_p[MAX_MAX_OPERANDS]; 140: enum machine_mode modes[MAX_MAX_OPERANDS]; 1.1.1.2 root 141: char strict_low[MAX_MAX_OPERANDS]; 142: char outfun; /* Nonzero means this has an output function */ 1.1.1.4 root 143: char *machine_info; /* machine-specific info string. */ 1.1 root 144: }; 145: 146: /* This variable points to the first link in the chain. */ 147: 148: struct data *insn_data; 149: 150: /* Pointer to the last link in the chain, so new elements 151: can be added at the end. */ 152: 153: struct data *end_of_insn_data; 154: 155: /* Nonzero if any match_operand has a constraint string; 156: implies that REGISTER_CONSTRAINTS will be defined 157: for this machine description. */ 158: 159: int have_constraints; 160: 161: void 162: output_prologue () 163: { 164: 165: printf ("/* Generated automatically by the program `genoutput'\n\ 166: from the machine description file `md'. */\n\n"); 167: 168: printf ("#include \"config.h\"\n"); 169: printf ("#include \"rtl.h\"\n"); 170: printf ("#include \"regs.h\"\n"); 1.1.1.6 root 171: printf ("#include \"real.h\"\n"); 1.1 root 172: printf ("#include \"conditions.h\"\n"); 173: printf ("#include \"insn-flags.h\"\n"); 174: printf ("#include \"insn-config.h\"\n\n"); 175: 1.1.1.4 root 176: printf ("#ifndef __STDC__\n"); 177: printf ("#define const\n"); 178: printf ("#endif\n\n"); 179: 180: printf ("#include \"output.h\"\n"); 1.1 root 181: printf ("#include \"aux-output.c\"\n\n"); 1.1.1.4 root 182: 183: /* Make sure there is at least a dummy definition of INSN_MACHINE_INFO. */ 184: printf ("#ifndef INSN_MACHINE_INFO\n"); 185: printf ("#define INSN_MACHINE_INFO struct dummy1 {int i;}\n"); 186: printf ("#endif\n\n"); 1.1 root 187: } 188: 189: void 190: output_epilogue () 191: { 192: register struct data *d; 193: 1.1.1.4 root 194: printf ("\nchar * const insn_template[] =\n {\n"); 1.1 root 195: for (d = insn_data; d; d = d->next) 196: { 197: if (d->template) 198: printf (" \"%s\",\n", d->template); 199: else 200: printf (" 0,\n"); 201: } 202: printf (" };\n"); 203: 1.1.1.4 root 204: printf ("\nchar *(*const insn_outfun[])() =\n {\n"); 1.1.1.2 root 205: for (d = insn_data; d; d = d->next) 206: { 207: if (d->outfun) 1.1.1.3 root 208: printf (" output_%d,\n", d->code_number); 1.1.1.2 root 209: else 210: printf (" 0,\n"); 211: } 212: printf (" };\n"); 213: 1.1.1.4 root 214: printf ("\nrtx (*const insn_gen_function[]) () =\n {\n"); 1.1 root 215: for (d = insn_data; d; d = d->next) 216: { 217: if (d->name) 218: printf (" gen_%s,\n", d->name); 219: else 220: printf (" 0,\n"); 221: } 222: printf (" };\n"); 223: 1.1.1.4 root 224: printf ("\nconst int insn_n_operands[] =\n {\n"); 1.1 root 225: for (d = insn_data; d; d = d->next) 226: { 227: printf (" %d,\n", d->n_operands); 228: } 229: printf (" };\n"); 230: 1.1.1.4 root 231: printf ("\nconst int insn_n_dups[] =\n {\n"); 1.1 root 232: for (d = insn_data; d; d = d->next) 233: { 234: printf (" %d,\n", d->n_dups); 235: } 236: printf (" };\n"); 237: 238: if (have_constraints) 239: { 1.1.1.4 root 240: printf ("\nchar *const insn_operand_constraint[][MAX_RECOG_OPERANDS] =\n {\n"); 1.1 root 241: for (d = insn_data; d; d = d->next) 242: { 1.1.1.5 root 243: register int i, n = 0, start; 1.1 root 244: printf (" {"); 1.1.1.5 root 245: /* Make sure all the operands have the same number of 246: alternatives in their constraints. 247: Let N be that number. */ 248: for (start = 0; start < d->n_operands; start++) 249: if (d->op_n_alternatives[start] > 0) 250: { 251: if (n == 0) 252: n = d->op_n_alternatives[start]; 253: else if (n != d->op_n_alternatives[start]) 1.1.1.6 root 254: error ("wrong number of alternatives in operand %d of insn number %d", 1.1.1.5 root 255: start, d->code_number); 256: } 257: /* Record the insn's overall number of alternatives. */ 258: d->n_alternatives = n; 259: 1.1 root 260: for (i = 0; i < d->n_operands; i++) 1.1.1.2 root 261: { 262: if (d->constraints[i] == 0) 263: printf (" \"\","); 264: else 265: printf (" \"%s\",", d->constraints[i]); 266: } 1.1 root 267: if (d->n_operands == 0) 268: printf (" 0"); 269: printf (" },\n"); 270: } 271: printf (" };\n"); 272: } 273: else 274: { 1.1.1.4 root 275: printf ("\nconst char insn_operand_address_p[][MAX_RECOG_OPERANDS] =\n {\n"); 1.1 root 276: for (d = insn_data; d; d = d->next) 277: { 278: register int i; 279: printf (" {"); 280: for (i = 0; i < d->n_operands; i++) 281: printf (" %d,", d->address_p[i]); 282: if (d->n_operands == 0) 283: printf (" 0"); 284: printf (" },\n"); 285: } 286: printf (" };\n"); 287: } 288: 1.1.1.4 root 289: printf ("\nconst enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS] =\n {\n"); 1.1 root 290: for (d = insn_data; d; d = d->next) 291: { 292: register int i; 293: printf (" {"); 294: for (i = 0; i < d->n_operands; i++) 295: printf (" %smode,", GET_MODE_NAME (d->modes[i])); 296: if (d->n_operands == 0) 297: printf (" VOIDmode"); 298: printf (" },\n"); 299: } 300: printf (" };\n"); 1.1.1.2 root 301: 1.1.1.4 root 302: printf ("\nconst char insn_operand_strict_low[][MAX_RECOG_OPERANDS] =\n {\n"); 1.1.1.2 root 303: for (d = insn_data; d; d = d->next) 304: { 305: register int i; 306: printf (" {"); 307: for (i = 0; i < d->n_operands; i++) 308: printf (" %d,", d->strict_low[i]); 309: if (d->n_operands == 0) 310: printf (" 0"); 311: printf (" },\n"); 312: } 313: printf (" };\n"); 314: 1.1.1.4 root 315: printf ("\nint (*const insn_operand_predicate[][MAX_RECOG_OPERANDS])() =\n {\n"); 1.1.1.2 root 316: for (d = insn_data; d; d = d->next) 317: { 318: register int i; 319: printf (" {"); 320: for (i = 0; i < d->n_operands; i++) 321: printf (" %s,", ((d->predicates[i] && d->predicates[i][0]) 322: ? d->predicates[i] : "0")); 323: if (d->n_operands == 0) 324: printf (" 0"); 325: printf (" },\n"); 326: } 327: printf (" };\n"); 1.1.1.4 root 328: 329: printf ("\nconst INSN_MACHINE_INFO insn_machine_info[] =\n {\n"); 330: for (d = insn_data; d; d = d->next) 331: { 332: if (d->machine_info) 333: printf (" {%s},\n", d->machine_info); 334: else 335: printf(" {0},\n"); 336: } 337: printf(" };\n"); 1.1.1.5 root 338: 339: printf ("\nconst int insn_n_alternatives[] =\n {\n"); 340: for (d = insn_data; d; d = d->next) 341: { 342: if (d->n_alternatives) 343: printf (" %d,\n", d->n_alternatives); 344: else 345: printf(" 0,\n"); 346: } 347: printf(" };\n"); 1.1 root 348: } 349: 350: /* scan_operands (X) stores in max_opno the largest operand 351: number present in X, if that is larger than the previous 352: value of max_opno. It stores all the constraints in `constraints' 1.1.1.2 root 353: and all the machine modes in `modes'. 354: 355: THIS_ADDRESS_P is nonzero if the containing rtx was an ADDRESS. 356: THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */ 1.1 root 357: 358: int max_opno; 359: int num_dups; 360: char *constraints[MAX_MAX_OPERANDS]; 1.1.1.5 root 361: int op_n_alternatives[MAX_MAX_OPERANDS]; 1.1.1.2 root 362: char *predicates[MAX_MAX_OPERANDS]; 1.1 root 363: char address_p[MAX_MAX_OPERANDS]; 364: enum machine_mode modes[MAX_MAX_OPERANDS]; 1.1.1.2 root 365: char strict_low[MAX_MAX_OPERANDS]; 1.1 root 366: 367: void 1.1.1.2 root 368: scan_operands (part, this_address_p, this_strict_low) 1.1 root 369: rtx part; 370: int this_address_p; 1.1.1.2 root 371: int this_strict_low; 1.1 root 372: { 373: register int i, j; 1.1.1.2 root 374: register RTX_CODE code; 1.1 root 375: register char *format_ptr; 376: 1.1.1.2 root 377: if (part == 0) 378: return; 379: 380: code = GET_CODE (part); 381: 1.1 root 382: if (code == MATCH_OPERAND) 383: { 1.1.1.2 root 384: int opno = XINT (part, 0); 385: if (opno > max_opno) 386: max_opno = opno; 387: if (max_opno >= MAX_MAX_OPERANDS) 1.1.1.6 root 388: error ("Too many operands (%d) in one instruction pattern.\n", 1.1 root 389: max_opno + 1); 1.1.1.2 root 390: modes[opno] = GET_MODE (part); 391: strict_low[opno] = this_strict_low; 392: predicates[opno] = XSTR (part, 1); 393: constraints[opno] = XSTR (part, 2); 1.1 root 394: if (XSTR (part, 2) != 0 && *XSTR (part, 2) != 0) 1.1.1.5 root 395: { 396: op_n_alternatives[opno] = n_occurrences (',', XSTR (part, 2)) + 1; 397: have_constraints = 1; 398: } 1.1.1.2 root 399: address_p[opno] = this_address_p; 1.1 root 400: return; 401: } 402: 1.1.1.5 root 403: if (code == MATCH_OPERATOR) 404: { 405: int opno = XINT (part, 0); 406: if (opno > max_opno) 407: max_opno = opno; 408: if (max_opno >= MAX_MAX_OPERANDS) 1.1.1.6 root 409: error ("Too many operands (%d) in one instruction pattern.\n", 1.1.1.5 root 410: max_opno + 1); 411: modes[opno] = GET_MODE (part); 412: strict_low[opno] = 0; 413: predicates[opno] = XSTR (part, 1); 414: constraints[opno] = 0; 415: address_p[opno] = 0; 416: for (i = 0; i < XVECLEN (part, 2); i++) 417: scan_operands (XVECEXP (part, 2, i), 0, 0); 418: return; 419: } 420: 1.1 root 421: if (code == MATCH_DUP) 422: { 423: ++num_dups; 424: return; 425: } 426: 427: if (code == ADDRESS) 428: { 1.1.1.2 root 429: scan_operands (XEXP (part, 0), 1, 0); 430: return; 431: } 432: 433: if (code == STRICT_LOW_PART) 434: { 435: scan_operands (XEXP (part, 0), 0, 1); 1.1 root 436: return; 437: } 438: 439: format_ptr = GET_RTX_FORMAT (GET_CODE (part)); 440: 441: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) 442: switch (*format_ptr++) 443: { 444: case 'e': 1.1.1.2 root 445: scan_operands (XEXP (part, i), 0, 0); 1.1 root 446: break; 447: case 'E': 448: if (XVEC (part, i) != NULL) 449: for (j = 0; j < XVECLEN (part, i); j++) 1.1.1.2 root 450: scan_operands (XVECEXP (part, i, j), 0, 0); 1.1 root 451: break; 452: } 453: } 454: 1.1.1.2 root 455: /* Look at a define_insn just read. Assign its code number. 1.1 root 456: Record on insn_data the template and the number of arguments. 1.1.1.2 root 457: If the insn has a hairy output action, output a function for now. */ 1.1 root 458: 459: void 460: gen_insn (insn) 461: rtx insn; 462: { 463: register struct data *d = (struct data *) xmalloc (sizeof (struct data)); 464: register int i; 465: 466: d->code_number = next_code_number++; 467: if (XSTR (insn, 0)[0]) 468: d->name = XSTR (insn, 0); 469: else 470: d->name = 0; 471: 472: /* Build up the list in the same order as the insns are seen 473: in the machine description. */ 474: d->next = 0; 475: if (end_of_insn_data) 476: end_of_insn_data->next = d; 477: else 478: insn_data = d; 479: 480: end_of_insn_data = d; 481: 482: max_opno = -1; 483: num_dups = 0; 484: 1.1.1.2 root 485: mybzero (constraints, sizeof constraints); 1.1.1.5 root 486: mybzero (op_n_alternatives, sizeof op_n_alternatives); 1.1.1.2 root 487: mybzero (predicates, sizeof predicates); 488: mybzero (address_p, sizeof address_p); 489: mybzero (modes, sizeof modes); 490: mybzero (strict_low, sizeof strict_low); 1.1 root 491: for (i = 0; i < XVECLEN (insn, 1); i++) 1.1.1.2 root 492: scan_operands (XVECEXP (insn, 1, i), 0, 0); 1.1 root 493: d->n_operands = max_opno + 1; 494: d->n_dups = num_dups; 1.1.1.2 root 495: mybcopy (constraints, d->constraints, sizeof constraints); 1.1.1.5 root 496: mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); 1.1.1.2 root 497: mybcopy (predicates, d->predicates, sizeof predicates); 498: mybcopy (address_p, d->address_p, sizeof address_p); 499: mybcopy (modes, d->modes, sizeof modes); 500: mybcopy (strict_low, d->strict_low, sizeof strict_low); 1.1.1.4 root 501: d->machine_info = XSTR (insn, 4); 1.1 root 502: 503: /* We need to consider only the instructions whose assembler code template 504: starts with a *. These are the ones where the template is really 505: C code to run to decide on a template to use. 506: So for all others just return now. */ 507: 508: if (XSTR (insn, 3)[0] != '*') 509: { 510: d->template = XSTR (insn, 3); 1.1.1.2 root 511: d->outfun = 0; 1.1 root 512: return; 513: } 514: 515: d->template = 0; 1.1.1.2 root 516: d->outfun = 1; 517: 518: printf ("\nchar *\n"); 519: printf ("output_%d (operands, insn)\n", d->code_number); 520: printf (" rtx *operands;\n"); 521: printf (" rtx insn;\n"); 522: printf ("{\n"); 523: /* The following is done in a funny way to get around problems in 524: VAX-11 "C" on VMS. It is the equivalent of: 525: printf ("%s\n", &(XSTR (insn, 3)[1])); */ 526: { 527: register char *cp = &(XSTR (insn, 3)[1]); 528: while (*cp) putchar (*cp++); 529: putchar ('\n'); 530: } 531: printf ("}\n"); 1.1 root 532: } 533: 1.1.1.2 root 534: /* Look at a define_peephole just read. Assign its code number. 535: Record on insn_data the template and the number of arguments. 536: If the insn has a hairy output action, output it now. */ 537: 538: void 539: gen_peephole (peep) 540: rtx peep; 541: { 542: register struct data *d = (struct data *) xmalloc (sizeof (struct data)); 543: register int i; 544: 545: d->code_number = next_code_number++; 546: d->name = 0; 547: 548: /* Build up the list in the same order as the insns are seen 549: in the machine description. */ 550: d->next = 0; 551: if (end_of_insn_data) 552: end_of_insn_data->next = d; 553: else 554: insn_data = d; 555: 556: end_of_insn_data = d; 557: 558: max_opno = -1; 559: mybzero (constraints, sizeof constraints); 1.1.1.5 root 560: mybzero (op_n_alternatives, sizeof op_n_alternatives); 1.1.1.2 root 561: 562: /* Get the number of operands by scanning all the 563: patterns of the peephole optimizer. 564: But ignore all the rest of the information thus obtained. */ 565: for (i = 0; i < XVECLEN (peep, 0); i++) 566: scan_operands (XVECEXP (peep, 0, i), 0, 0); 567: 568: d->n_operands = max_opno + 1; 569: d->n_dups = 0; 570: mybcopy (constraints, d->constraints, sizeof constraints); 1.1.1.5 root 571: mybcopy (op_n_alternatives, d->op_n_alternatives, sizeof op_n_alternatives); 1.1.1.2 root 572: mybzero (d->predicates, sizeof predicates); 573: mybzero (d->address_p, sizeof address_p); 574: mybzero (d->modes, sizeof modes); 575: mybzero (d->strict_low, sizeof strict_low); 1.1.1.4 root 576: d->machine_info = XSTR (peep, 3); 1.1.1.2 root 577: 578: /* We need to consider only the instructions whose assembler code template 579: starts with a *. These are the ones where the template is really 580: C code to run to decide on a template to use. 581: So for all others just return now. */ 582: 583: if (XSTR (peep, 2)[0] != '*') 584: { 585: d->template = XSTR (peep, 2); 586: d->outfun = 0; 587: return; 588: } 589: 590: d->template = 0; 591: d->outfun = 1; 592: 593: printf ("\nchar *\n"); 594: printf ("output_%d (operands, insn)\n", d->code_number); 595: printf (" rtx *operands;\n"); 596: printf (" rtx insn;\n"); 597: printf ("{\n"); 598: printf ("%s\n", &(XSTR (peep, 2)[1])); 599: printf ("}\n"); 600: } 601: 602: /* Process a define_expand just read. Assign its code number, 603: only for the purposes of `insn_gen_function'. */ 604: 605: void 606: gen_expand (insn) 607: rtx insn; 608: { 609: register struct data *d = (struct data *) xmalloc (sizeof (struct data)); 610: register int i; 611: 612: d->code_number = next_code_number++; 613: if (XSTR (insn, 0)[0]) 614: d->name = XSTR (insn, 0); 615: else 616: d->name = 0; 617: 618: /* Build up the list in the same order as the insns are seen 619: in the machine description. */ 620: d->next = 0; 621: if (end_of_insn_data) 622: end_of_insn_data->next = d; 623: else 624: insn_data = d; 625: 626: end_of_insn_data = d; 627: 628: max_opno = -1; 629: num_dups = 0; 630: 631: /* Scan the operands to get the specified predicates and modes, 632: since expand_binop needs to know them. */ 633: 634: mybzero (predicates, sizeof predicates); 635: mybzero (modes, sizeof modes); 636: if (XVEC (insn, 1)) 637: for (i = 0; i < XVECLEN (insn, 1); i++) 638: scan_operands (XVECEXP (insn, 1, i), 0, 0); 639: d->n_operands = max_opno + 1; 640: mybcopy (predicates, d->predicates, sizeof predicates); 641: mybcopy (modes, d->modes, sizeof modes); 642: 643: mybzero (d->constraints, sizeof constraints); 1.1.1.5 root 644: mybzero (d->op_n_alternatives, sizeof op_n_alternatives); 1.1.1.2 root 645: mybzero (d->address_p, sizeof address_p); 646: mybzero (d->strict_low, sizeof strict_low); 647: 648: d->n_dups = 0; 649: d->template = 0; 650: d->outfun = 0; 1.1.1.4 root 651: d->machine_info = 0; 1.1.1.2 root 652: } 653: 654: int 1.1 root 655: xmalloc (size) 656: { 657: register int val = malloc (size); 658: 659: if (val == 0) 1.1.1.2 root 660: fatal ("virtual memory exhausted"); 1.1 root 661: return val; 662: } 663: 664: int 665: xrealloc (ptr, size) 666: char *ptr; 667: int size; 668: { 669: int result = realloc (ptr, size); 670: if (!result) 1.1.1.2 root 671: fatal ("virtual memory exhausted"); 1.1 root 672: return result; 673: } 674: 675: void 1.1.1.2 root 676: mybzero (b, length) 677: register char *b; 678: register int length; 679: { 680: while (length-- > 0) 681: *b++ = 0; 682: } 683: 684: void 685: mybcopy (b1, b2, length) 686: register char *b1; 687: register char *b2; 688: register int length; 689: { 690: while (length-- > 0) 691: *b2++ = *b1++; 692: } 693: 694: void 1.1 root 695: fatal (s, a1, a2) 696: { 1.1.1.2 root 697: fprintf (stderr, "genoutput: "); 1.1 root 698: fprintf (stderr, s, a1, a2); 699: fprintf (stderr, "\n"); 1.1.1.2 root 700: exit (FATAL_EXIT_CODE); 1.1 root 701: } 1.1.1.6 root 702: 703: void 704: error (s, a1, a2) 705: { 706: fprintf (stderr, "genoutput: "); 707: fprintf (stderr, s, a1, a2); 708: fprintf (stderr, "\n"); 709: } 1.1 root 710: 1.1.1.2 root 711: int 1.1 root 712: main (argc, argv) 713: int argc; 714: char **argv; 715: { 716: rtx desc; 717: FILE *infile; 718: extern rtx read_rtx (); 719: register int c; 720: 1.1.1.2 root 721: obstack_init (rtl_obstack); 1.1 root 722: 723: if (argc <= 1) 724: fatal ("No input file name."); 725: 726: infile = fopen (argv[1], "r"); 727: if (infile == 0) 728: { 729: perror (argv[1]); 1.1.1.2 root 730: exit (FATAL_EXIT_CODE); 1.1 root 731: } 732: 733: init_rtl (); 734: 735: output_prologue (); 736: next_code_number = 0; 737: have_constraints = 0; 738: 739: /* Read the machine description. */ 740: 741: while (1) 742: { 743: c = read_skip_spaces (infile); 744: if (c == EOF) 745: break; 746: ungetc (c, infile); 747: 748: desc = read_rtx (infile); 1.1.1.2 root 749: if (GET_CODE (desc) == DEFINE_INSN) 750: gen_insn (desc); 751: if (GET_CODE (desc) == DEFINE_PEEPHOLE) 752: gen_peephole (desc); 753: if (GET_CODE (desc) == DEFINE_EXPAND) 754: gen_expand (desc); 1.1 root 755: } 756: 757: output_epilogue (); 758: 1.1.1.2 root 759: fflush (stdout); 760: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); 1.1 root 761: } 1.1.1.5 root 762: 763: int 764: n_occurrences (c, s) 765: char c; 766: char *s; 767: { 768: int n = 0; 769: while (*s) 770: n += (*s++ == c); 771: return n; 772: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.