|
|
1.1 ! root 1: /* Top level of GNU C compiler ! 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* This is the top level of cc1. ! 23: It parses command args, opens files, invokes the various passes ! 24: in the proper order, and counts the time used by each. ! 25: Error messages and low-level interface to malloc also handled here. */ ! 26: ! 27: #include "config.h" ! 28: #include <stdio.h> ! 29: #include <signal.h> ! 30: ! 31: #ifdef USG ! 32: #include <sys/param.h> ! 33: #include <sys/times.h> ! 34: #include <time.h> /* Correct for hpux at least. Is it good on other USG? */ ! 35: #else ! 36: #ifndef VMS ! 37: #include <sys/time.h> ! 38: #include <sys/resource.h> ! 39: #endif ! 40: #endif ! 41: ! 42: #ifndef _TYPES_ ! 43: #include <sys/types.h> ! 44: #endif ! 45: #include <sys/stat.h> ! 46: ! 47: #include "tree.h" ! 48: #include "c-tree.h" ! 49: #include "rtl.h" ! 50: #include "flags.h" ! 51: ! 52: extern int yydebug; ! 53: ! 54: extern FILE *finput; ! 55: ! 56: extern void init_lex (); ! 57: extern void init_decl_processing (); ! 58: extern void init_tree (); ! 59: extern void init_rtl (); ! 60: extern void init_optabs (); ! 61: extern void init_reg_sets (); ! 62: extern void dump_flow_info (); ! 63: extern void dump_local_alloc (); ! 64: ! 65: void rest_of_decl_compilation (); ! 66: void error (); ! 67: void error_with_file_and_line (); ! 68: void set_target_switch (); ! 69: ! 70: /* Bit flags that specify the machine subtype we are compiling for. ! 71: Bits are tested using macros TARGET_... defined in the tm-...h file ! 72: and set by `-m...' switches. */ ! 73: ! 74: int target_flags; ! 75: ! 76: /* Name of current original source file (what was input to cpp). ! 77: This comes from each #-command in the actual input. */ ! 78: ! 79: char *input_filename; ! 80: ! 81: /* Name of top-level original source file (what was input to cpp). ! 82: This comes from the first #-command in the actual input. */ ! 83: ! 84: char *main_input_filename; ! 85: ! 86: /* Current line number in real source file. */ ! 87: ! 88: extern int lineno; ! 89: ! 90: /* FUNCTION_DECL for function now being parsed or compiled. */ ! 91: ! 92: extern tree current_function_decl; ! 93: ! 94: /* Name to use as base of names for dump output files. */ ! 95: ! 96: char *dump_base_name; ! 97: ! 98: /* Flags saying which kinds of debugging dump have been requested. */ ! 99: ! 100: int rtl_dump = 0; ! 101: int rtl_dump_and_exit = 0; ! 102: int jump_opt_dump = 0; ! 103: int cse_dump = 0; ! 104: int loop_dump = 0; ! 105: int flow_dump = 0; ! 106: int combine_dump = 0; ! 107: int local_reg_dump = 0; ! 108: int global_reg_dump = 0; ! 109: int jump2_opt_dump = 0; ! 110: ! 111: /* 1 => write gdb debugging output (using symout.c). -g ! 112: 2 => write dbx debugging output (using dbxout.c). -G */ ! 113: ! 114: int write_symbols = 0; ! 115: ! 116: /* Nonzero means do optimizations. -opt. */ ! 117: ! 118: int optimize = 0; ! 119: ! 120: /* Nonzero for -fforce-mem: load memory value into a register ! 121: before arithmetic on it. This makes better cse but slower compilation. */ ! 122: ! 123: int flag_force_mem = 0; ! 124: ! 125: /* Nonzero for -fforce-addr: load memory address into a register before ! 126: reference to memory. This makes better cse but slower compilation. */ ! 127: ! 128: int flag_force_addr = 0; ! 129: ! 130: /* Nonzero for -fdefer-pop: don't pop args after each function call; ! 131: instead save them up to pop many calls' args with one insns. */ ! 132: ! 133: int flag_defer_pop = 1; ! 134: ! 135: /* Nonzero for -ffloat-store: don't allocate floats and doubles ! 136: in extended-precision registers. */ ! 137: ! 138: int flag_float_store = 0; ! 139: ! 140: /* Nonzero for -fcombine-regs: ! 141: allow instruction combiner to combine an insn ! 142: that just copies one reg to another. */ ! 143: ! 144: int flag_combine_regs = 0; ! 145: ! 146: /* Nonzero for -fwritable-strings: ! 147: store string constants in data segment and don't uniquize them. */ ! 148: ! 149: int flag_writable_strings = 0; ! 150: ! 151: /* Nonzero means don't put addresses of constant functions in registers. ! 152: Used for compiling the Unix kernel, where strange substitutions are ! 153: done on the assembly output. */ ! 154: ! 155: int flag_no_function_cse = 0; ! 156: ! 157: /* Nonzero for -fomit-frame-pointer: ! 158: don't make a frame pointer in simple functions that don't require one. */ ! 159: ! 160: int flag_omit_frame_pointer = 0; ! 161: ! 162: /* Nonzero to inhibit use of define_optimization peephole opts. */ ! 163: ! 164: int flag_no_peephole = 0; ! 165: ! 166: /* Nonzero means `char' should be signed. */ ! 167: ! 168: int flag_signed_char; ! 169: ! 170: /* Nonzero means allow type mismatches in conditional expressions; ! 171: just make their values `void'. */ ! 172: ! 173: int flag_cond_mismatch; ! 174: ! 175: /* Nonzero means don't recognize the keyword `asm'. */ ! 176: ! 177: int flag_no_asm; ! 178: ! 179: /* Nonzero means warn about implicit declarations. */ ! 180: ! 181: int warn_implicit; ! 182: ! 183: /* Nonzero means warn about function definitions that default the return type ! 184: or that use a null return and have a return-type other than void. */ ! 185: ! 186: int warn_return_type; ! 187: ! 188: /* Nonzero means do some things the same way PCC does. */ ! 189: ! 190: int flag_traditional; ! 191: ! 192: /* Nonzero means all references through pointers are volatile. */ ! 193: ! 194: int flag_volatile; ! 195: ! 196: /* Nonzero means do stupid register allocation. -noreg. ! 197: This and `optimize' are controlled by different switches in cc1, ! 198: but normally cc controls them both with the -O switch. */ ! 199: ! 200: int obey_regdecls = 0; ! 201: ! 202: /* Don't print functions as they are compiled and don't print ! 203: times taken by the various passes. -quiet. */ ! 204: ! 205: int quiet_flag = 0; ! 206: ! 207: /* Don't print warning messages. -w. */ ! 208: ! 209: int inhibit_warnings = 0; ! 210: ! 211: /* Do print extra warnings (such as for uninitialized variables). -W. */ ! 212: ! 213: int extra_warnings = 0; ! 214: ! 215: /* Number of error messages and warning messages so far. */ ! 216: ! 217: int errorcount = 0; ! 218: int warningcount = 0; ! 219: ! 220: /* Nonzero if generating code to do profiling. */ ! 221: ! 222: int profile_flag = 0; ! 223: ! 224: /* Nonzero for -pedantic switch: warn about anything ! 225: that standard C forbids. */ ! 226: ! 227: int pedantic = 0; ! 228: ! 229: /* Nonzero for -finline-functions: ok to inline functions that look like ! 230: good inline candidates. */ ! 231: ! 232: int flag_inline_functions; ! 233: ! 234: /* Nonzero for -fkeep-inline-functions: even if we make a function ! 235: go inline everywhere, keep its defintion around for debugging ! 236: purposes. */ ! 237: ! 238: int flag_keep_inline_functions; ! 239: ! 240: /* Name for output file of assembly code, specified with -o. */ ! 241: ! 242: char *asm_file_name; ! 243: ! 244: /* Name for output file of GDB symbol segment, specified with -symout. */ ! 245: ! 246: char *sym_file_name; ! 247: ! 248: /* Output files for assembler code (real compiler output) ! 249: and debugging dumps. */ ! 250: ! 251: FILE *asm_out_file; ! 252: FILE *rtl_dump_file; ! 253: FILE *jump_opt_dump_file; ! 254: FILE *cse_dump_file; ! 255: FILE *loop_dump_file; ! 256: FILE *flow_dump_file; ! 257: FILE *combine_dump_file; ! 258: FILE *local_reg_dump_file; ! 259: FILE *global_reg_dump_file; ! 260: FILE *jump2_opt_dump_file; ! 261: ! 262: /* Time accumulators, to count the total time spent in various passes. */ ! 263: ! 264: int parse_time; ! 265: int varconst_time; ! 266: int integration_time; ! 267: int jump_time; ! 268: int cse_time; ! 269: int loop_time; ! 270: int flow_time; ! 271: int combine_time; ! 272: int local_alloc_time; ! 273: int global_alloc_time; ! 274: int final_time; ! 275: int symout_time; ! 276: int dump_time; ! 277: ! 278: /* Return time used so far, in microseconds. */ ! 279: ! 280: int ! 281: gettime () ! 282: { ! 283: #ifdef USG ! 284: struct tms tms; ! 285: #else ! 286: #ifndef VMS ! 287: struct rusage rusage; ! 288: #else /* VMS */ ! 289: struct ! 290: { ! 291: int proc_user_time; ! 292: int proc_system_time; ! 293: int child_user_time; ! 294: int child_system_time; ! 295: } vms_times; ! 296: #endif ! 297: #endif ! 298: ! 299: if (quiet_flag) ! 300: return 0; ! 301: ! 302: #ifdef USG ! 303: times (&tms); ! 304: return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ); ! 305: #else ! 306: #ifndef VMS ! 307: getrusage (0, &rusage); ! 308: return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec ! 309: + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec); ! 310: #else /* VMS */ ! 311: times (&vms_times); ! 312: return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000; ! 313: #endif ! 314: #endif ! 315: } ! 316: ! 317: #define TIMEVAR(VAR, BODY) \ ! 318: do { int otime = gettime (); BODY; VAR += gettime () - otime; } while (0) ! 319: ! 320: void ! 321: print_time (str, total) ! 322: char *str; ! 323: int total; ! 324: { ! 325: fprintf (stderr, ! 326: "time in %s: %d.%06d\n", ! 327: str, total / 1000000, total % 1000000); ! 328: } ! 329: ! 330: /* Count an error or warning. Return 1 if the message should be printed. */ ! 331: ! 332: int ! 333: count_error (warningp) ! 334: int warningp; ! 335: { ! 336: if (warningp && inhibit_warnings) ! 337: return 0; ! 338: ! 339: if (warningp) ! 340: warningcount++; ! 341: else ! 342: errorcount++; ! 343: ! 344: return 1; ! 345: } ! 346: ! 347: /* Print a fatal error message. NAME is the text. ! 348: Also include a system error message based on `errno'. */ ! 349: ! 350: void ! 351: pfatal_with_name (name) ! 352: char *name; ! 353: { ! 354: fprintf (stderr, "cc1: "); ! 355: perror (name); ! 356: exit (35); ! 357: } ! 358: ! 359: void ! 360: fatal_io_error (name) ! 361: char *name; ! 362: { ! 363: fprintf (stderr, "cc1:%s: I/O error\n", name); ! 364: exit (35); ! 365: } ! 366: ! 367: void ! 368: fatal (s) ! 369: char *s; ! 370: { ! 371: error (s, 0); ! 372: exit (34); ! 373: } ! 374: ! 375: /* Called when the start of a function definition is parsed, ! 376: this function prints on stderr the name of the function. */ ! 377: ! 378: void ! 379: announce_function (decl) ! 380: tree decl; ! 381: { ! 382: if (! quiet_flag) ! 383: { ! 384: fprintf (stderr, " %s", IDENTIFIER_POINTER (DECL_NAME (decl))); ! 385: fflush (stderr); ! 386: } ! 387: } ! 388: ! 389: /* Prints out, if necessary, the name of the current function ! 390: which caused an error. Called from all error and warning functions. */ ! 391: ! 392: void ! 393: report_error_function() ! 394: { ! 395: static tree last_error_function = NULL; ! 396: ! 397: if (last_error_function != current_function_decl) ! 398: { ! 399: if (current_function_decl == NULL) ! 400: { ! 401: if (!quiet_flag) ! 402: fprintf (stderr, "\n"); ! 403: fprintf (stderr, "At top level:\n"); ! 404: } ! 405: else ! 406: { ! 407: if (!quiet_flag) ! 408: /* We already know this info. Don't print it twice. ! 409: But make sure we are at the beginning of a line. */ ! 410: fprintf (stderr, "\n"); ! 411: else ! 412: fprintf (stderr, "In function %s:\n", ! 413: IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); ! 414: } ! 415: last_error_function = current_function_decl; ! 416: } ! 417: } ! 418: ! 419: /* Report an error at the current line number. ! 420: S and V are a string and an arg for `printf'. */ ! 421: ! 422: void ! 423: error (s, v) ! 424: char *s; ! 425: int v; /* @@also used as pointer */ ! 426: { ! 427: error_with_file_and_line (input_filename, lineno, s, v); ! 428: } ! 429: ! 430: /* Report an error at line LINE of file FILE. ! 431: S and V are a string and an arg for `printf'. */ ! 432: ! 433: void ! 434: error_with_file_and_line (file, line, s, v) ! 435: char *file; ! 436: int line; ! 437: char *s; ! 438: int v; ! 439: { ! 440: count_error (0); ! 441: ! 442: report_error_function (); ! 443: ! 444: if (file) ! 445: fprintf (stderr, "%s:%d: ", file, line); ! 446: else ! 447: fprintf (stderr, "cc1: "); ! 448: fprintf (stderr, s, v); ! 449: fprintf (stderr, "\n"); ! 450: } ! 451: ! 452: /* Report an error at the declaration DECL. ! 453: S is string which uses %s to substitute the declaration name. */ ! 454: ! 455: void ! 456: error_with_decl (decl, s) ! 457: tree decl; ! 458: char *s; ! 459: { ! 460: count_error (0); ! 461: ! 462: report_error_function (); ! 463: ! 464: fprintf (stderr, "%s:%d: ", ! 465: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 466: ! 467: if (DECL_NAME (decl)) ! 468: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl))); ! 469: else ! 470: fprintf (stderr, s, "((anonymous))"); ! 471: fprintf (stderr, "\n"); ! 472: } ! 473: ! 474: /* Report a warning at line LINE. ! 475: S and V are a string and an arg for `printf'. */ ! 476: ! 477: void ! 478: warning_with_line (line, s, v) ! 479: int line; ! 480: char *s; ! 481: int v; ! 482: { ! 483: if (count_error (1) == 0) ! 484: return; ! 485: ! 486: report_error_function (); ! 487: ! 488: if (input_filename) ! 489: fprintf (stderr, "%s:%d: ", input_filename, line); ! 490: else ! 491: fprintf (stderr, "cc1: "); ! 492: ! 493: fprintf (stderr, "warning: "); ! 494: fprintf (stderr, s, v); ! 495: fprintf (stderr, "\n"); ! 496: } ! 497: ! 498: /* Report a warning at the current line number. ! 499: S and V are a string and an arg for `printf'. */ ! 500: ! 501: void ! 502: warning (s, v) ! 503: char *s; ! 504: int v; /* @@also used as pointer */ ! 505: { ! 506: warning_with_line (lineno, s, v); ! 507: } ! 508: ! 509: /* Report a warning at the declaration DECL. ! 510: S is string which uses %s to substitute the declaration name. */ ! 511: ! 512: void ! 513: warning_with_decl (decl, s) ! 514: tree decl; ! 515: char *s; ! 516: { ! 517: if (count_error (1) == 0) ! 518: return; ! 519: ! 520: report_error_function (); ! 521: ! 522: fprintf (stderr, "%s:%d: ", ! 523: DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); ! 524: ! 525: fprintf (stderr, "warning: "); ! 526: if (DECL_NAME (decl)) ! 527: fprintf (stderr, s, IDENTIFIER_POINTER (DECL_NAME (decl))); ! 528: else ! 529: fprintf (stderr, s, "((anonymous))"); ! 530: fprintf (stderr, "\n"); ! 531: } ! 532: ! 533: /* When `malloc.c' is compiled with `rcheck' defined, ! 534: it calls this function to report clobberage. */ ! 535: ! 536: void ! 537: botch (s) ! 538: { ! 539: abort (); ! 540: } ! 541: ! 542: /* Same as `malloc' but report error if no memory available. */ ! 543: ! 544: int ! 545: xmalloc (size) ! 546: unsigned size; ! 547: { ! 548: register int value = (int) malloc (size); ! 549: if (value == 0) ! 550: fatal ("Virtual memory exhausted."); ! 551: return value; ! 552: } ! 553: ! 554: /* Same as `realloc' but report error if no memory available. */ ! 555: ! 556: int ! 557: xrealloc (ptr, size) ! 558: char *ptr; ! 559: int size; ! 560: { ! 561: int result = realloc (ptr, size); ! 562: if (!result) ! 563: fatal ("Virtual memory exhausted."); ! 564: return result; ! 565: } ! 566: ! 567: /* Return the logarithm of X, base 2, considering X unsigned, ! 568: if X is a power of 2. Otherwise, returns -1. */ ! 569: ! 570: int ! 571: exact_log2 (x) ! 572: register unsigned int x; ! 573: { ! 574: register int log = 0; ! 575: for (log = 0; log < HOST_BITS_PER_INT; log++) ! 576: if (x == (1 << log)) ! 577: return log; ! 578: return -1; ! 579: } ! 580: ! 581: /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X. ! 582: If X is 0, return -1. */ ! 583: ! 584: int ! 585: floor_log2 (x) ! 586: register unsigned int x; ! 587: { ! 588: register int log = 0; ! 589: for (log = 0; log < HOST_BITS_PER_INT; log++) ! 590: if ((x & ((-1) << log)) == 0) ! 591: return log - 1; ! 592: return HOST_BITS_PER_INT - 1; ! 593: } ! 594: ! 595: /* Compile an entire file of output from cpp, named NAME. ! 596: Write a file of assembly output and various debugging dumps. */ ! 597: ! 598: static void ! 599: compile_file (name) ! 600: char *name; ! 601: { ! 602: tree globals; ! 603: int start_time; ! 604: int dump_base_name_length = strlen (dump_base_name); ! 605: ! 606: parse_time = 0; ! 607: varconst_time = 0; ! 608: integration_time = 0; ! 609: jump_time = 0; ! 610: cse_time = 0; ! 611: loop_time = 0; ! 612: flow_time = 0; ! 613: combine_time = 0; ! 614: local_alloc_time = 0; ! 615: global_alloc_time = 0; ! 616: final_time = 0; ! 617: symout_time = 0; ! 618: dump_time = 0; ! 619: ! 620: /* Open input file. */ ! 621: ! 622: finput = fopen (name, "r"); ! 623: if (finput == 0) ! 624: pfatal_with_name (name); ! 625: ! 626: /* Initialize data in various passes. */ ! 627: ! 628: init_tree (); ! 629: init_lex (); ! 630: init_rtl (); ! 631: init_emit_once (); ! 632: init_decl_processing (); ! 633: init_optabs (); ! 634: ! 635: /* If rtl dump desired, open the output file. */ ! 636: if (rtl_dump) ! 637: { ! 638: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 639: strcpy (dumpname, dump_base_name); ! 640: strcat (dumpname, ".rtl"); ! 641: rtl_dump_file = fopen (dumpname, "w"); ! 642: if (rtl_dump_file == 0) ! 643: pfatal_with_name (dumpname); ! 644: } ! 645: ! 646: /* If jump_opt dump desired, open the output file. */ ! 647: if (jump_opt_dump) ! 648: { ! 649: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 650: strcpy (dumpname, dump_base_name); ! 651: strcat (dumpname, ".jump"); ! 652: jump_opt_dump_file = fopen (dumpname, "w"); ! 653: if (jump_opt_dump_file == 0) ! 654: pfatal_with_name (dumpname); ! 655: } ! 656: ! 657: /* If cse dump desired, open the output file. */ ! 658: if (cse_dump) ! 659: { ! 660: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 661: strcpy (dumpname, dump_base_name); ! 662: strcat (dumpname, ".cse"); ! 663: cse_dump_file = fopen (dumpname, "w"); ! 664: if (cse_dump_file == 0) ! 665: pfatal_with_name (dumpname); ! 666: } ! 667: ! 668: /* If loop dump desired, open the output file. */ ! 669: if (loop_dump) ! 670: { ! 671: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 672: strcpy (dumpname, dump_base_name); ! 673: strcat (dumpname, ".loop"); ! 674: loop_dump_file = fopen (dumpname, "w"); ! 675: if (loop_dump_file == 0) ! 676: pfatal_with_name (dumpname); ! 677: } ! 678: ! 679: /* If flow dump desired, open the output file. */ ! 680: if (flow_dump) ! 681: { ! 682: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 683: strcpy (dumpname, dump_base_name); ! 684: strcat (dumpname, ".flow"); ! 685: flow_dump_file = fopen (dumpname, "w"); ! 686: if (flow_dump_file == 0) ! 687: pfatal_with_name (dumpname); ! 688: } ! 689: ! 690: /* If combine dump desired, open the output file. */ ! 691: if (combine_dump) ! 692: { ! 693: register char *dumpname = (char *) xmalloc (dump_base_name_length + 10); ! 694: strcpy (dumpname, dump_base_name); ! 695: strcat (dumpname, ".combine"); ! 696: combine_dump_file = fopen (dumpname, "w"); ! 697: if (combine_dump_file == 0) ! 698: pfatal_with_name (dumpname); ! 699: } ! 700: ! 701: /* If local_reg dump desired, open the output file. */ ! 702: if (local_reg_dump) ! 703: { ! 704: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 705: strcpy (dumpname, dump_base_name); ! 706: strcat (dumpname, ".lreg"); ! 707: local_reg_dump_file = fopen (dumpname, "w"); ! 708: if (local_reg_dump_file == 0) ! 709: pfatal_with_name (dumpname); ! 710: } ! 711: ! 712: /* If global_reg dump desired, open the output file. */ ! 713: if (global_reg_dump) ! 714: { ! 715: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 716: strcpy (dumpname, dump_base_name); ! 717: strcat (dumpname, ".greg"); ! 718: global_reg_dump_file = fopen (dumpname, "w"); ! 719: if (global_reg_dump_file == 0) ! 720: pfatal_with_name (dumpname); ! 721: } ! 722: ! 723: /* If jump2_opt dump desired, open the output file. */ ! 724: if (jump2_opt_dump) ! 725: { ! 726: register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); ! 727: strcpy (dumpname, dump_base_name); ! 728: strcat (dumpname, ".jump2"); ! 729: jump2_opt_dump_file = fopen (dumpname, "w"); ! 730: if (jump2_opt_dump_file == 0) ! 731: pfatal_with_name (dumpname); ! 732: } ! 733: ! 734: /* Open assembler code output file. */ ! 735: ! 736: { ! 737: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 738: int len = strlen (dump_base_name); ! 739: strcpy (dumpname, dump_base_name); ! 740: if (len > 2 && ! strcmp (".c", dumpname + len - 2)) ! 741: dumpname[len - 2] = 0; ! 742: else if (len > 3 && ! strcmp (".co", dumpname + len - 3)) ! 743: dumpname[len - 3] = 0; ! 744: strcat (dumpname, ".s"); ! 745: if (asm_file_name == 0) ! 746: { ! 747: asm_file_name = (char *) malloc (strlen (dumpname) + 1); ! 748: strcpy (asm_file_name, dumpname); ! 749: } ! 750: asm_out_file = fopen (asm_file_name, "w"); ! 751: if (asm_out_file == 0) ! 752: pfatal_with_name (asm_file_name ? asm_file_name : dumpname); ! 753: fprintf (asm_out_file, ASM_FILE_START); ! 754: } ! 755: ! 756: input_filename = name; ! 757: ! 758: /* the beginning of the file is a new line; check for # */ ! 759: /* With luck, we discover the real source file's name from that ! 760: and put it in input_filename. */ ! 761: check_newline (); ! 762: ! 763: /* If GDB symbol table desired, open the GDB symbol output file. */ ! 764: if (write_symbols == 1) ! 765: { ! 766: register char *dumpname = (char *) xmalloc (dump_base_name_length + 6); ! 767: int len = strlen (dump_base_name); ! 768: strcpy (dumpname, dump_base_name); ! 769: if (len > 2 && ! strcmp (".c", dumpname + len - 2)) ! 770: dumpname[len - 2] = 0; ! 771: else if (len > 3 && ! strcmp (".co", dumpname + len - 3)) ! 772: dumpname[len - 3] = 0; ! 773: strcat (dumpname, ".sym"); ! 774: if (sym_file_name == 0) ! 775: sym_file_name = dumpname; ! 776: symout_init (sym_file_name, asm_out_file, input_filename); ! 777: } ! 778: ! 779: /* If dbx symbol table desired, initialize writing it ! 780: and output the predefined types. */ ! 781: if (write_symbols == 2) ! 782: dbxout_init (asm_out_file, main_input_filename); ! 783: ! 784: /* Initialize yet another pass. */ ! 785: ! 786: init_final (main_input_filename); ! 787: ! 788: start_time = gettime (); ! 789: ! 790: /* Call the parser, which parses the entire file ! 791: (calling rest_of_compilation for each function). */ ! 792: ! 793: yyparse (); ! 794: ! 795: /* Compilation is now finished except for writing ! 796: what's left of the symbol table output. */ ! 797: ! 798: parse_time += gettime () - start_time; ! 799: ! 800: parse_time -= varconst_time; ! 801: ! 802: globals = getdecls (); ! 803: ! 804: /* Really define vars that have had only a tentative definition. ! 805: Really output inline functions that must actually be callable ! 806: and have not been output so far. */ ! 807: ! 808: { ! 809: tree decl; ! 810: for (decl = globals; decl; decl = TREE_CHAIN (decl)) ! 811: { ! 812: if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) ! 813: && ! TREE_ASM_WRITTEN (decl)) ! 814: rest_of_decl_compilation (decl, 0, 1, 1); ! 815: if (TREE_CODE (decl) == FUNCTION_DECL ! 816: && ! TREE_ASM_WRITTEN (decl) ! 817: && DECL_INITIAL (decl) != 0 ! 818: && TREE_ADDRESSABLE (decl)) ! 819: output_inline_function (decl); ! 820: } ! 821: } ! 822: ! 823: /* Do dbx symbols */ ! 824: if (write_symbols == 2) ! 825: TIMEVAR (symout_time, ! 826: { ! 827: dbxout_tags (gettags ()); ! 828: dbxout_types (get_permanent_types ()); ! 829: }); ! 830: ! 831: /* Do gdb symbols */ ! 832: if (write_symbols == 1) ! 833: TIMEVAR (symout_time, ! 834: { ! 835: struct stat statbuf; ! 836: fstat (fileno (finput), &statbuf); ! 837: symout_types (get_permanent_types ()); ! 838: symout_top_blocks (globals, gettags ()); ! 839: symout_finish (name, statbuf.st_ctime); ! 840: }); ! 841: ! 842: /* Close the dump files. */ ! 843: ! 844: if (rtl_dump) ! 845: fclose (rtl_dump_file); ! 846: ! 847: if (jump_opt_dump) ! 848: fclose (jump_opt_dump_file); ! 849: ! 850: if (cse_dump) ! 851: fclose (cse_dump_file); ! 852: ! 853: if (loop_dump) ! 854: fclose (loop_dump_file); ! 855: ! 856: if (flow_dump) ! 857: fclose (flow_dump_file); ! 858: ! 859: if (combine_dump) ! 860: { ! 861: dump_combine_total_stats (combine_dump_file); ! 862: fclose (combine_dump_file); ! 863: } ! 864: ! 865: if (local_reg_dump) ! 866: fclose (local_reg_dump_file); ! 867: ! 868: if (global_reg_dump) ! 869: fclose (global_reg_dump_file); ! 870: ! 871: if (jump2_opt_dump) ! 872: fclose (jump2_opt_dump_file); ! 873: ! 874: /* Close non-debugging input and output files. */ ! 875: ! 876: fclose (finput); ! 877: if (ferror (asm_out_file) != 0) ! 878: fatal_io_error (asm_file_name); ! 879: fclose (asm_out_file); ! 880: ! 881: /* Print the times. */ ! 882: ! 883: if (! quiet_flag) ! 884: { ! 885: fprintf (stderr,"\n"); ! 886: print_time ("parse", parse_time); ! 887: print_time ("integration", integration_time); ! 888: print_time ("jump", jump_time); ! 889: print_time ("cse", cse_time); ! 890: print_time ("loop", loop_time); ! 891: print_time ("flow", flow_time); ! 892: print_time ("combine", combine_time); ! 893: print_time ("local-alloc", local_alloc_time); ! 894: print_time ("global-alloc", global_alloc_time); ! 895: print_time ("final", final_time); ! 896: print_time ("varconst", varconst_time); ! 897: print_time ("symout", symout_time); ! 898: print_time ("dump", dump_time); ! 899: } ! 900: } ! 901: ! 902: /* This is called from finish_decl (within yyparse) ! 903: for each declaration of a function or variable. ! 904: This does nothing for automatic variables. ! 905: Otherwise, it sets up the RTL and outputs any assembler code ! 906: (label definition, storage allocation and initialization). ! 907: ! 908: DECL is the declaration. If ASMSPEC is nonzero, it specifies ! 909: the assembler symbol name to be used. TOP_LEVEL is nonzero ! 910: if this declaration is not within a function. */ ! 911: ! 912: void ! 913: rest_of_decl_compilation (decl, asmspec, top_level, at_end) ! 914: tree decl; ! 915: tree asmspec; ! 916: int top_level; ! 917: int at_end; ! 918: { ! 919: /* Declarations of variables, and of functions defined elsewhere. */ ! 920: ! 921: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl)) ! 922: TIMEVAR (varconst_time, ! 923: { ! 924: assemble_variable (decl, asmspec, top_level, write_symbols, at_end); ! 925: }); ! 926: else if (write_symbols == 2 && TREE_CODE (decl) == TYPE_DECL) ! 927: TIMEVAR (varconst_time, dbxout_symbol (decl, 0)); ! 928: ! 929: if (top_level) ! 930: { ! 931: if (write_symbols == 1) ! 932: { ! 933: TIMEVAR (symout_time, ! 934: { ! 935: /* The initizations make types when they contain ! 936: string constants. The types are on the temporary ! 937: obstack, so output them now before they go away. */ ! 938: symout_types (get_temporary_types ()); ! 939: }); ! 940: } ! 941: else ! 942: /* Clean out the temporary type list, since the types will go away. */ ! 943: get_temporary_types (); ! 944: } ! 945: } ! 946: ! 947: /* This is called from finish_function (within yyparse) ! 948: after each top-level definition is parsed. ! 949: It is supposed to compile that function or variable ! 950: and output the assembler code for it. ! 951: After we return, the tree storage is freed. */ ! 952: ! 953: void ! 954: rest_of_compilation (decl) ! 955: tree decl; ! 956: { ! 957: register rtx insns; ! 958: int start_time = gettime (); ! 959: int tem; ! 960: ! 961: /* If we are reconsidering an inline function ! 962: at the end of compilation, skip the stuff for making it inline. */ ! 963: ! 964: if (DECL_SAVED_INSNS (decl) == 0) ! 965: { ! 966: ! 967: /* If requested, consider whether to make this function inline. */ ! 968: if (flag_inline_functions || TREE_INLINE (decl)) ! 969: { ! 970: TIMEVAR (integration_time, ! 971: { ! 972: int specd = TREE_INLINE (decl); ! 973: char *lose = function_cannot_inline_p (decl); ! 974: if (lose != 0 && specd) ! 975: warning_with_decl (decl, lose); ! 976: if (lose == 0) ! 977: save_for_inline (decl); ! 978: else ! 979: TREE_INLINE (decl) = 0; ! 980: }); ! 981: } ! 982: ! 983: insns = get_insns (); ! 984: ! 985: /* Dump the rtl code if we are dumping rtl. */ ! 986: ! 987: if (rtl_dump) ! 988: TIMEVAR (dump_time, ! 989: { ! 990: fprintf (rtl_dump_file, "\n;; Function %s\n\n", ! 991: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 992: if (DECL_SAVED_INSNS (decl)) ! 993: fprintf (rtl_dump_file, ";; (integrable)\n\n"); ! 994: print_rtl (rtl_dump_file, insns); ! 995: fflush (rtl_dump_file); ! 996: }); ! 997: ! 998: /* If function is inline, and we don't yet know whether to ! 999: compile it by itself, defer decision till end of compilation. ! 1000: finish_compilation will call rest_of_compilation again ! 1001: for those functions that need to be output. */ ! 1002: ! 1003: if (TREE_PUBLIC (decl) == 0 ! 1004: && TREE_INLINE (decl) ! 1005: && ! flag_keep_inline_functions) ! 1006: goto exit_rest_of_compilation; ! 1007: } ! 1008: ! 1009: if (rtl_dump_and_exit) ! 1010: goto exit_rest_of_compilation; ! 1011: ! 1012: TREE_ASM_WRITTEN (decl) = 1; ! 1013: ! 1014: insns = get_insns (); ! 1015: ! 1016: /* Copy any shared structure that should not be shared. */ ! 1017: ! 1018: unshare_all_rtl (insns); ! 1019: ! 1020: /* See if we have allocated stack slots that are not directly addressable. ! 1021: If so, scan all the insns and create explicit address computation ! 1022: for all references to such slots. */ ! 1023: /* fixup_stack_slots (); */ ! 1024: ! 1025: /* Do jump optimization the first time, if -opt. ! 1026: Also do it if -W, but in that case it doesn't change the rtl code, ! 1027: it only computes whether control can drop off the end of the function. */ ! 1028: ! 1029: if (optimize || extra_warnings || warn_return_type) ! 1030: TIMEVAR (jump_time, jump_optimize (insns, 0, 0)); ! 1031: ! 1032: /* Dump rtl code after jump, if we are doing that. */ ! 1033: ! 1034: if (jump_opt_dump) ! 1035: TIMEVAR (dump_time, ! 1036: { ! 1037: fprintf (jump_opt_dump_file, "\n;; Function %s\n\n", ! 1038: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1039: print_rtl (jump_opt_dump_file, insns); ! 1040: fflush (jump_opt_dump_file); ! 1041: }); ! 1042: ! 1043: /* Perform common subexpression elimination. ! 1044: Nonzero value from `cse_main' means that jumps were simplified ! 1045: and some code may now be unreachable, so do ! 1046: jump optimization again. */ ! 1047: ! 1048: if (optimize) ! 1049: { ! 1050: TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 0)); ! 1051: ! 1052: TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num ())); ! 1053: ! 1054: if (tem) ! 1055: TIMEVAR (jump_time, jump_optimize (insns, 0, 0)); ! 1056: } ! 1057: ! 1058: /* Dump rtl code after cse, if we are doing that. */ ! 1059: ! 1060: if (cse_dump) ! 1061: TIMEVAR (dump_time, ! 1062: { ! 1063: fprintf (cse_dump_file, "\n;; Function %s\n\n", ! 1064: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1065: print_rtl (cse_dump_file, insns); ! 1066: fflush (cse_dump_file); ! 1067: }); ! 1068: ! 1069: if (loop_dump) ! 1070: TIMEVAR (dump_time, ! 1071: { ! 1072: fprintf (loop_dump_file, "\n;; Function %s\n\n", ! 1073: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1074: }); ! 1075: ! 1076: /* Move constant computations out of loops. */ ! 1077: ! 1078: if (optimize) ! 1079: { ! 1080: TIMEVAR (loop_time, ! 1081: { ! 1082: reg_scan (insns, max_reg_num (), 1); ! 1083: loop_optimize (insns, max_reg_num (), ! 1084: loop_dump ? loop_dump_file : 0); ! 1085: }); ! 1086: } ! 1087: ! 1088: /* Dump rtl code after loop opt, if we are doing that. */ ! 1089: ! 1090: if (loop_dump) ! 1091: TIMEVAR (dump_time, ! 1092: { ! 1093: print_rtl (loop_dump_file, insns); ! 1094: fflush (loop_dump_file); ! 1095: }); ! 1096: ! 1097: /* Now we choose between stupid (pcc-like) register allocation ! 1098: (if we got the -noreg switch and not -opt) ! 1099: and smart register allocation. */ ! 1100: ! 1101: if (optimize) /* Stupid allocation probably won't work */ ! 1102: obey_regdecls = 0; /* if optimizations being done. */ ! 1103: ! 1104: regclass_init (); ! 1105: ! 1106: /* Print function header into flow dump now ! 1107: because doing the flow analysis makes some of the dump. */ ! 1108: ! 1109: if (flow_dump) ! 1110: TIMEVAR (dump_time, ! 1111: { ! 1112: fprintf (flow_dump_file, "\n;; Function %s\n\n", ! 1113: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1114: }); ! 1115: ! 1116: if (obey_regdecls) ! 1117: { ! 1118: TIMEVAR (flow_time, ! 1119: { ! 1120: regclass (insns, max_reg_num ()); ! 1121: stupid_life_analysis (insns, max_reg_num (), ! 1122: flow_dump_file); ! 1123: }); ! 1124: } ! 1125: else ! 1126: { ! 1127: /* Do control and data flow analysis, ! 1128: and write some of the results to dump file. */ ! 1129: ! 1130: TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (), ! 1131: flow_dump_file)); ! 1132: if (extra_warnings) ! 1133: uninitialized_vars_warning (DECL_INITIAL (decl)); ! 1134: } ! 1135: ! 1136: /* Dump rtl after flow analysis. */ ! 1137: ! 1138: if (flow_dump) ! 1139: TIMEVAR (dump_time, ! 1140: { ! 1141: print_rtl (flow_dump_file, insns); ! 1142: fflush (flow_dump_file); ! 1143: }); ! 1144: ! 1145: /* If -opt, try combining insns through substitution. */ ! 1146: ! 1147: if (optimize) ! 1148: TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ())); ! 1149: ! 1150: /* Dump rtl code after insn combination. */ ! 1151: ! 1152: if (combine_dump) ! 1153: TIMEVAR (dump_time, ! 1154: { ! 1155: fprintf (combine_dump_file, "\n;; Function %s\n\n", ! 1156: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1157: dump_combine_stats (combine_dump_file); ! 1158: print_rtl (combine_dump_file, insns); ! 1159: fflush (combine_dump_file); ! 1160: }); ! 1161: ! 1162: /* Unless we did stupid register allocation, ! 1163: allocate pseudo-regs that are used only within 1 basic block. */ ! 1164: ! 1165: if (!obey_regdecls) ! 1166: TIMEVAR (local_alloc_time, ! 1167: { ! 1168: regclass (insns, max_reg_num ()); ! 1169: local_alloc (); ! 1170: }); ! 1171: ! 1172: /* Dump rtl code after allocating regs within basic blocks. */ ! 1173: ! 1174: if (local_reg_dump) ! 1175: TIMEVAR (dump_time, ! 1176: { ! 1177: fprintf (local_reg_dump_file, "\n;; Function %s\n\n", ! 1178: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1179: dump_flow_info (local_reg_dump_file); ! 1180: dump_local_alloc (local_reg_dump_file); ! 1181: print_rtl (local_reg_dump_file, insns); ! 1182: fflush (local_reg_dump_file); ! 1183: }); ! 1184: ! 1185: if (global_reg_dump) ! 1186: TIMEVAR (dump_time, ! 1187: fprintf (global_reg_dump_file, "\n;; Function %s\n\n", ! 1188: IDENTIFIER_POINTER (DECL_NAME (decl)))); ! 1189: ! 1190: /* Unless we did stupid register allocation, ! 1191: allocate remaining pseudo-regs, then do the reload pass ! 1192: fixing up any insns that are invalid. */ ! 1193: ! 1194: TIMEVAR (global_alloc_time, ! 1195: { ! 1196: if (!obey_regdecls) ! 1197: global_alloc (global_reg_dump ? global_reg_dump_file : 0); ! 1198: else ! 1199: reload (insns, 0, ! 1200: global_reg_dump ? global_reg_dump_file : 0); ! 1201: }); ! 1202: ! 1203: if (global_reg_dump) ! 1204: TIMEVAR (dump_time, ! 1205: { ! 1206: dump_global_regs (global_reg_dump_file); ! 1207: print_rtl (global_reg_dump_file, insns); ! 1208: fflush (global_reg_dump_file); ! 1209: }); ! 1210: ! 1211: /* One more attempt to remove jumps to .+1 ! 1212: left by dead-store-elimination. ! 1213: Also do cross-jumping this time ! 1214: and delete no-op move insns. */ ! 1215: ! 1216: if (optimize) ! 1217: { ! 1218: TIMEVAR (jump_time, jump_optimize (insns, 1, 1)); ! 1219: } ! 1220: ! 1221: /* Dump rtl code after jump, if we are doing that. */ ! 1222: ! 1223: if (jump2_opt_dump) ! 1224: TIMEVAR (dump_time, ! 1225: { ! 1226: fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n", ! 1227: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1228: print_rtl (jump2_opt_dump_file, insns); ! 1229: fflush (jump2_opt_dump_file); ! 1230: }); ! 1231: ! 1232: /* Now turn the rtl into assembler code. */ ! 1233: ! 1234: TIMEVAR (final_time, ! 1235: { ! 1236: assemble_function (decl); ! 1237: final_start_function (insns, asm_out_file, ! 1238: write_symbols, optimize); ! 1239: final (insns, asm_out_file, ! 1240: write_symbols, optimize); ! 1241: final_end_function (insns, asm_out_file, ! 1242: write_symbols, optimize); ! 1243: fflush (asm_out_file); ! 1244: }); ! 1245: ! 1246: /* Write GDB symbols if requested */ ! 1247: ! 1248: if (write_symbols == 1) ! 1249: { ! 1250: TIMEVAR (symout_time, ! 1251: { ! 1252: symout_types (get_permanent_types ()); ! 1253: symout_types (get_temporary_types ()); ! 1254: ! 1255: DECL_BLOCK_SYMTAB_ADDRESS (decl) ! 1256: = symout_function (DECL_INITIAL (decl), ! 1257: DECL_ARGUMENTS (decl), 0); ! 1258: }); ! 1259: } ! 1260: else ! 1261: get_temporary_types (); ! 1262: ! 1263: /* Write DBX symbols if requested */ ! 1264: ! 1265: if (write_symbols == 2) ! 1266: TIMEVAR (symout_time, dbxout_function (decl)); ! 1267: ! 1268: exit_rest_of_compilation: ! 1269: ! 1270: /* The parsing time is all the time spent in yyparse ! 1271: *except* what is spent in this function. */ ! 1272: ! 1273: parse_time -= gettime () - start_time; ! 1274: } ! 1275: ! 1276: /* Entry point of cc1. Decode command args, then call compile_file. ! 1277: Exit code is 35 if can't open files, 34 if fatal error, ! 1278: 33 if had nonfatal errors, else success. */ ! 1279: ! 1280: int ! 1281: main (argc, argv, envp) ! 1282: int argc; ! 1283: char **argv; ! 1284: char **envp; ! 1285: { ! 1286: register int i; ! 1287: char *filename = 0; ! 1288: int print_mem_flag = 0; ! 1289: ! 1290: #ifdef RLIMIT_STACK ! 1291: /* Get rid of any avoidable limit on stack size. */ ! 1292: { ! 1293: struct rlimit rlim; ! 1294: ! 1295: /* Set the stack limit huge so that alloca does not fail. */ ! 1296: getrlimit (RLIMIT_STACK, &rlim); ! 1297: rlim.rlim_cur = rlim.rlim_max; ! 1298: setrlimit (RLIMIT_STACK, &rlim); ! 1299: } ! 1300: #endif /* RLIMIT_STACK */ ! 1301: ! 1302: /* Initialize whether `char' is signed. */ ! 1303: flag_signed_char = DEFAULT_SIGNED_CHAR; ! 1304: ! 1305: /* Initialize reg-sets now so switches may override. */ ! 1306: init_reg_sets (); ! 1307: ! 1308: target_flags = 0; ! 1309: set_target_switch (""); ! 1310: ! 1311: for (i = 1; i < argc; i++) ! 1312: if (argv[i][0] == '-') ! 1313: { ! 1314: register char *str = argv[i] + 1; ! 1315: if (str[0] == 'Y') ! 1316: str++; ! 1317: ! 1318: if (str[0] == 'm') ! 1319: set_target_switch (&str[1]); ! 1320: else if (!strcmp (str, "dumpbase")) ! 1321: { ! 1322: dump_base_name = argv[++i]; ! 1323: } ! 1324: else if (str[0] == 'd') ! 1325: { ! 1326: register char *p = &str[1]; ! 1327: while (*p) ! 1328: switch (*p++) ! 1329: { ! 1330: case 'c': ! 1331: combine_dump = 1; ! 1332: break; ! 1333: case 'f': ! 1334: flow_dump = 1; ! 1335: break; ! 1336: case 'g': ! 1337: global_reg_dump = 1; ! 1338: break; ! 1339: case 'j': ! 1340: jump_opt_dump = 1; ! 1341: break; ! 1342: case 'J': ! 1343: jump2_opt_dump = 1; ! 1344: break; ! 1345: case 'l': ! 1346: local_reg_dump = 1; ! 1347: break; ! 1348: case 'L': ! 1349: loop_dump = 1; ! 1350: break; ! 1351: case 'm': ! 1352: print_mem_flag = 1; ! 1353: break; ! 1354: case 'r': ! 1355: rtl_dump = 1; ! 1356: break; ! 1357: case 's': ! 1358: cse_dump = 1; ! 1359: break; ! 1360: case 'y': ! 1361: yydebug = 1; ! 1362: break; ! 1363: } ! 1364: } ! 1365: else if (str[0] == 'f') ! 1366: { ! 1367: register char *p = &str[1]; ! 1368: if (!strcmp (p, "float-store")) ! 1369: flag_float_store = 1; ! 1370: else if (!strcmp (p, "traditional")) ! 1371: flag_traditional = 1; ! 1372: else if (!strcmp (p, "volatile")) ! 1373: flag_volatile = 1; ! 1374: else if (!strcmp (p, "defer-pop")) ! 1375: flag_defer_pop = 1; ! 1376: else if (!strcmp (p, "no-defer-pop")) ! 1377: flag_defer_pop = 0; ! 1378: else if (!strcmp (p, "omit-frame-pointer")) ! 1379: flag_omit_frame_pointer = 1; ! 1380: else if (!strcmp (p, "no-omit-frame-pointer")) ! 1381: flag_omit_frame_pointer = 0; ! 1382: else if (!strcmp (p, "no-peephole")) ! 1383: flag_no_peephole = 1; ! 1384: else if (!strcmp (p, "signed-char")) ! 1385: flag_signed_char = 1; ! 1386: else if (!strcmp (p, "unsigned-char")) ! 1387: flag_signed_char = 0; ! 1388: else if (!strcmp (p, "force-mem")) ! 1389: flag_force_mem = 1; ! 1390: else if (!strcmp (p, "force-addr")) ! 1391: flag_force_addr = 1; ! 1392: else if (!strcmp (p, "combine-regs")) ! 1393: flag_combine_regs = 1; ! 1394: else if (!strcmp (p, "writable-strings")) ! 1395: flag_writable_strings = 1; ! 1396: else if (!strcmp (p, "no-function-cse")) ! 1397: flag_no_function_cse = 1; ! 1398: else if (!strcmp (p, "cond-mismatch")) ! 1399: flag_cond_mismatch = 1; ! 1400: else if (!strcmp (p, "no-asm")) ! 1401: flag_no_asm = 1; ! 1402: else if (!strncmp (p, "fixed-", 6)) ! 1403: fix_register (&p[6], 1, 1); ! 1404: else if (!strncmp (p, "call-used-", 10)) ! 1405: fix_register (&p[10], 0, 1); ! 1406: else if (!strncmp (p, "call-saved-", 11)) ! 1407: fix_register (&p[11], 0, 0); ! 1408: else if (!strcmp (p, "inline-functions")) ! 1409: flag_inline_functions = 1; ! 1410: else if (!strcmp (p, "keep-inline-functions")) ! 1411: flag_keep_inline_functions = 1; ! 1412: else ! 1413: error ("Invalid option, `%s'", argv[i]); ! 1414: } ! 1415: else if (!strcmp (str, "noreg")) ! 1416: obey_regdecls = 1; ! 1417: else if (!strcmp (str, "opt")) ! 1418: optimize = 1; ! 1419: else if (!strcmp (str, "pedantic")) ! 1420: pedantic = 1; ! 1421: else if (!strcmp (str, "traditional")) ! 1422: flag_traditional = 1; ! 1423: else if (!strcmp (str, "ansi")) ! 1424: flag_no_asm = 1; ! 1425: else if (!strcmp (str, "quiet")) ! 1426: quiet_flag = 1; ! 1427: else if (!strcmp (str, "version")) ! 1428: { ! 1429: extern char version_string[]; ! 1430: printf ("GNU C version %s", version_string); ! 1431: #ifdef TARGET_VERSION ! 1432: TARGET_VERSION; ! 1433: #endif ! 1434: #ifdef __GNUC__ ! 1435: #ifndef __VERSION__ ! 1436: #define __VERSION__ "[unknown]" ! 1437: #endif ! 1438: printf (" compiled by GNU C version %s.\n", __VERSION__); ! 1439: #else ! 1440: printf (" compiled by CC.\n"); ! 1441: #endif ! 1442: } ! 1443: else if (!strcmp (str, "w")) ! 1444: inhibit_warnings = 1; ! 1445: else if (!strcmp (str, "W")) ! 1446: extra_warnings = 1; ! 1447: else if (!strcmp (str, "Wimplicit")) ! 1448: warn_implicit = 1; ! 1449: else if (!strcmp (str, "Wreturn-type")) ! 1450: warn_return_type = 1; ! 1451: else if (!strcmp (str, "Wcomment")) ! 1452: ; /* cpp handles this one. */ ! 1453: else if (!strcmp (str, "Wall")) ! 1454: { ! 1455: extra_warnings = 1; ! 1456: warn_implicit = 1; ! 1457: warn_return_type = 1; ! 1458: } ! 1459: else if (!strcmp (str, "p")) ! 1460: profile_flag = 1; ! 1461: else if (!strcmp (str, "g")) ! 1462: write_symbols = 1; ! 1463: else if (!strcmp (str, "G")) ! 1464: write_symbols = 2; ! 1465: else if (!strcmp (str, "symout")) ! 1466: { ! 1467: if (write_symbols == 0) ! 1468: write_symbols = 1; ! 1469: sym_file_name = argv[++i]; ! 1470: } ! 1471: else if (!strcmp (str, "o")) ! 1472: { ! 1473: asm_file_name = argv[++i]; ! 1474: } ! 1475: else ! 1476: error ("Invalid switch, %s.", argv[i]); ! 1477: } ! 1478: else ! 1479: filename = argv[i]; ! 1480: ! 1481: if (filename == 0) ! 1482: fatal ("no input file specified"); ! 1483: ! 1484: if (dump_base_name == 0) ! 1485: dump_base_name = filename; ! 1486: ! 1487: #ifdef OVERRIDE_OPTIONS ! 1488: /* Some machines may reject certain combinations of options. */ ! 1489: OVERRIDE_OPTIONS; ! 1490: #endif ! 1491: ! 1492: compile_file (filename); ! 1493: ! 1494: #ifndef USG ! 1495: #ifndef VMS ! 1496: if (print_mem_flag) ! 1497: { ! 1498: extern char **environ; ! 1499: caddr_t lim = (caddr_t) sbrk (0); ! 1500: ! 1501: fprintf (stderr, "Data size %d.\n", ! 1502: (int) lim - (int) &environ); ! 1503: fflush (stderr); ! 1504: ! 1505: system ("ps v"); ! 1506: } ! 1507: #endif /* not VMS */ ! 1508: #endif /* not USG */ ! 1509: ! 1510: if (errorcount) ! 1511: exit (FATAL_EXIT_CODE); ! 1512: exit (SUCCESS_EXIT_CODE); ! 1513: return 34; ! 1514: } ! 1515: ! 1516: /* Decode -m switches. */ ! 1517: ! 1518: /* Here is a table, controlled by the tm-...h file, listing each -m switch ! 1519: and which bits in `target_switches' it should set or clear. ! 1520: If VALUE is positive, it is bits to set. ! 1521: If VALUE is negative, -VALUE is bits to clear. ! 1522: (The sign bit is not used so there is no confusion.) */ ! 1523: ! 1524: struct {char *name; int value;} target_switches [] ! 1525: = TARGET_SWITCHES; ! 1526: ! 1527: /* Decode the switch -mNAME. */ ! 1528: ! 1529: void ! 1530: set_target_switch (name) ! 1531: char *name; ! 1532: { ! 1533: register int j; ! 1534: for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++) ! 1535: if (!strcmp (target_switches[j].name, name)) ! 1536: { ! 1537: if (target_switches[j].value < 0) ! 1538: target_flags &= ~-target_switches[j].value; ! 1539: else ! 1540: target_flags |= target_switches[j].value; ! 1541: break; ! 1542: } ! 1543: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.