1/* Id: main.c,v 1.118 2012/03/22 18:51:40 plunky Exp */ 2/* $NetBSD: main.c,v 1.1.1.5 2012/03/26 14:26:49 plunky Exp $ */ 3 4/* 5 * Copyright (c) 2002 Anders Magnusson. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include "config.h" 31 32#ifdef HAVE_UNISTD_H 33#include <unistd.h> 34#endif 35#include <signal.h> 36#include <string.h> 37#include <stdlib.h> 38 39#include "pass1.h" 40#include "pass2.h" 41 42int bdebug, ddebug, edebug, idebug, ndebug; 43int odebug, pdebug, sdebug, tdebug, xdebug; 44int b2debug, c2debug, e2debug, f2debug, g2debug, o2debug; 45int r2debug, s2debug, t2debug, u2debug, x2debug; 46int gflag, kflag; 47int pflag, sflag; 48int sspflag; 49int xssa, xtailcall, xtemps, xdeljumps, xdce, xinline, xccp, xgnu89, xgnu99; 50int xuchar; 51int freestanding; 52char *prgname; 53 54static void prtstats(void); 55 56static void 57usage(void) 58{ 59 (void)fprintf(stderr, "usage: %s [option] [infile] [outfile]...\n", 60 prgname); 61 exit(1); 62} 63 64static void 65segvcatch(int a) 66{ 67 char buf[1024]; 68 int dummy; 69 70 snprintf(buf, sizeof buf, "%sinternal compiler error: %s, line %d\n", 71 nerrors ? "" : "major ", ftitle, lineno); 72 dummy = write(STDERR_FILENO, buf, strlen(buf)); 73 _exit(1); 74} 75 76static void 77xopt(char *str) 78{ 79 if (strcmp(str, "ssa") == 0) 80 xssa++; 81 else if (strcmp(str, "tailcall") == 0) 82 xtailcall++; 83 else if (strcmp(str, "temps") == 0) 84 xtemps++; 85 else if (strcmp(str, "deljumps") == 0) 86 xdeljumps++; 87 else if (strcmp(str, "dce") == 0) 88 xdce++; 89 else if (strcmp(str, "inline") == 0) 90 xinline++; 91 else if (strcmp(str, "ccp") == 0) 92 xccp++; 93 else if (strcmp(str, "gnu89") == 0) 94 xgnu89++; 95 else if (strcmp(str, "gnu99") == 0) 96 xgnu99++; 97 else if (strcmp(str, "uchar") == 0) 98 xuchar++; 99 else { 100 fprintf(stderr, "unknown -x option '%s'\n", str); 101 usage(); 102 } 103} 104 105static void 106fflags(char *str) 107{ 108 int flagval = 1; 109 110 if (strncmp("no-", str, 3) == 0) { 111 str += 3; 112 flagval = 0; 113 } 114 115 if (strcmp(str, "stack-protector") == 0) 116 sspflag = flagval; 117 else if (strcmp(str, "stack-protector-all") == 0) 118 sspflag = flagval; 119 else if (strncmp(str, "pack-struct", 11) == 0) 120 pragma_allpacked = (strlen(str) > 12 ? atoi(str+12) : 1); 121 else if (strcmp(str, "freestanding") == 0) 122 freestanding = flagval; 123 else { 124 fprintf(stderr, "unknown -f option '%s'\n", str); 125 usage(); 126 } 127} 128 129/* control multiple files */ 130int 131main(int argc, char *argv[]) 132{ 133 int ch; 134 135#ifdef TIMING 136 struct timeval t1, t2; 137 138 (void)gettimeofday(&t1, NULL); 139#endif 140 141 prgname = argv[0]; 142 143 while ((ch = getopt(argc, argv, "OT:VW:X:Z:f:gkm:psvwx:")) != -1) { 144 switch (ch) { 145#if !defined(MULTIPASS) || defined(PASS1) 146 case 'X': /* pass1 debugging */ 147 while (*optarg) 148 switch (*optarg++) { 149 case 'b': ++bdebug; break; /* buildtree */ 150 case 'd': ++ddebug; break; /* declarations */ 151 case 'e': ++edebug; break; /* pass1 exit */ 152 case 'i': ++idebug; break; /* initializations */ 153 case 'n': ++ndebug; break; /* node allocation */ 154 case 'o': ++odebug; break; /* optim */ 155 case 'p': ++pdebug; break; /* prototype */ 156 case 's': ++sdebug; break; /* inline */ 157 case 't': ++tdebug; break; /* type match */ 158 case 'x': ++xdebug; break; /* MD code */ 159 default: 160 fprintf(stderr, "unknown -X flag '%c'\n", 161 optarg[-1]); 162 exit(1); 163 } 164 break; 165#endif 166#if !defined(MULTIPASS) || defined(PASS2) 167 case 'Z': /* pass2 debugging */ 168 while (*optarg) 169 switch (*optarg++) { 170 case 'b': /* basic block and SSA building */ 171 ++b2debug; 172 break; 173 case 'c': /* code printout */ 174 ++c2debug; 175 break; 176 case 'e': /* print tree upon pass2 enter */ 177 ++e2debug; 178 break; 179 case 'f': /* instruction matching */ 180 ++f2debug; 181 break; 182 case 'g': /* print flow graphs */ 183 ++g2debug; 184 break; 185 case 'n': /* node allocation */ 186 ++ndebug; 187 break; 188 case 'o': /* instruction generator */ 189 ++o2debug; 190 break; 191 case 'r': /* register alloc/graph coloring */ 192 ++r2debug; 193 break; 194 case 's': /* shape matching */ 195 ++s2debug; 196 break; 197 case 't': /* type matching */ 198 ++t2debug; 199 break; 200 case 'u': /* Sethi-Ullman debugging */ 201 ++u2debug; 202 break; 203 case 'x': /* target specific */ 204 ++x2debug; 205 break; 206 default: 207 fprintf(stderr, "unknown -Z flag '%c'\n", 208 optarg[-1]); 209 exit(1); 210 } 211 break; 212#endif 213 case 'f': /* Language */ 214 fflags(optarg); 215 break; 216 217 case 'g': /* Debugging */ 218 ++gflag; 219 break; 220 221 case 'k': /* PIC code */ 222 ++kflag; 223 break; 224 225 case 'm': /* Target-specific */ 226 mflags(optarg); 227 break; 228 229 case 'p': /* Profiling */ 230 ++pflag; 231 break; 232 233 case 's': /* Statistics */ 234 ++sflag; 235 break; 236 237 case 'W': /* Enable different warnings */ 238 Wflags(optarg); 239 break; 240 241 case 'x': /* Different settings */ 242 xopt(optarg); 243 break; 244 245 case 'v': 246 printf("ccom: %s\n", VERSSTR); 247 break; 248 249 case '?': 250 default: 251 usage(); 252 } 253 } 254 argc -= optind; 255 argv += optind; 256 257 if (argc > 0 && strcmp(argv[0], "-") != 0) { 258 if (freopen(argv[0], "r", stdin) == NULL) { 259 fprintf(stderr, "open input file '%s':", 260 argv[0]); 261 perror(NULL); 262 exit(1); 263 } 264 } 265 if (argc > 1 && strcmp(argv[1], "-") != 0) { 266 if (freopen(argv[1], "w", stdout) == NULL) { 267 fprintf(stderr, "open output file '%s':", 268 argv[1]); 269 perror(NULL); 270 exit(1); 271 } 272 } 273 274 mkdope(); 275 signal(SIGSEGV, segvcatch); 276#ifdef SIGBUS 277 signal(SIGBUS, segvcatch); 278#endif 279 fregs = FREGS; /* number of free registers */ 280 lineno = 1; 281#ifdef GCC_COMPAT 282 gcc_init(); 283#endif 284 285 /* starts past any of the above */ 286 reached = 1; 287 288 bjobcode(); 289#ifndef TARGET_VALIST 290 { 291 NODE *p = block(NAME, NIL, NIL, PTR|CHAR, NULL, 0); 292 struct symtab *sp = lookup(addname("__builtin_va_list"), 0); 293 p->n_sp = sp; 294 defid(p, TYPEDEF); 295 nfree(p); 296 } 297#endif 298 complinit(); 299 300#ifdef STABS 301 if (gflag) { 302 stabs_file(argc ? argv[0] : ""); 303 stabs_init(); 304 } 305#endif 306 307 if (sspflag) 308 sspinit(); 309 310 (void) yyparse(); 311 yyaccpt(); 312 313 if (!nerrors) 314 lcommprint(); 315 316#ifdef STABS 317 if (gflag) 318 stabs_efile(argc ? argv[0] : ""); 319#endif 320 321 ejobcode( nerrors ? 1 : 0 ); 322 323#ifdef TIMING 324 (void)gettimeofday(&t2, NULL); 325 t2.tv_sec -= t1.tv_sec; 326 t2.tv_usec -= t1.tv_usec; 327 if (t2.tv_usec < 0) { 328 t2.tv_usec += 1000000; 329 t2.tv_sec -= 1; 330 } 331 fprintf(stderr, "ccom total time: %ld s %ld us\n", 332 t2.tv_sec, t2.tv_usec); 333#endif 334 335 if (sflag) 336 prtstats(); 337 338 return(nerrors?1:0); 339} 340 341void 342prtstats(void) 343{ 344 extern int nametabs, namestrlen, tmpallocsize, permallocsize; 345 extern int lostmem, arglistcnt, dimfuncnt, inlnodecnt, inlstatcnt; 346 extern int symtabcnt, suedefcnt; 347 348 fprintf(stderr, "Name table entries: %d pcs\n", nametabs); 349 fprintf(stderr, "Name string size: %d B\n", namestrlen); 350 fprintf(stderr, "Permanent allocated memory: %d B\n", permallocsize); 351 fprintf(stderr, "Temporary allocated memory: %d B\n", tmpallocsize); 352 fprintf(stderr, "Lost memory: %d B\n", lostmem); 353 fprintf(stderr, "Argument list unions: %d pcs\n", arglistcnt); 354 fprintf(stderr, "Dimension/function unions: %d pcs\n", dimfuncnt); 355 fprintf(stderr, "Struct/union/enum blocks: %d pcs\n", suedefcnt); 356 fprintf(stderr, "Inline node count: %d pcs\n", inlnodecnt); 357 fprintf(stderr, "Inline control blocks: %d pcs\n", inlstatcnt); 358 fprintf(stderr, "Permanent symtab entries: %d pcs\n", symtabcnt); 359} 360