c10.c (9261B)
1 /* 2 3 C compiler, part 2 4 5 Copyright 1972 Bell Telephone Laboratories, Inc. 6 7 */ 8 9 waste() /* waste space */ 10 { 11 waste(waste(waste),waste(waste),waste(waste)); 12 waste(waste(waste),waste(waste),waste(waste)); 13 waste(waste(waste),waste(waste),waste(waste)); 14 waste(waste(waste),waste(waste),waste(waste)); 15 waste(waste(waste),waste(waste),waste(waste)); 16 waste(waste(waste),waste(waste),waste(waste)); 17 waste(waste(waste),waste(waste),waste(waste)); 18 waste(waste(waste),waste(waste),waste(waste)); 19 } 20 main(argc, argv) 21 char argv[][]; 22 { 23 extern fout, fin, nerror, line; 24 extern getwrd, rcexpr, tmpfil; 25 extern cctab[], regtab[], efftab[], sptab[]; 26 int sp[], c, table[], tabtab[3][], tree; 27 28 if (argc<4) { 29 error("Arg count"); 30 exit(1); 31 } 32 if((fin=open(argv[1],0))<0) { 33 error("Cant't find %s", argv[1]); 34 exit(1); 35 } 36 if((fout=creat(argv[3],017))<0) { 37 error("Can't create %s", argv[3]); 38 exit(1); 39 } 40 tmpfil = argv[2]; 41 42 tabtab[0] = regtab; 43 tabtab[1] = efftab; 44 tabtab[2] = cctab; 45 tabtab[3] = sptab; 46 while(c=getchar()) { 47 if(c=='#') { 48 sp = 0; 49 c = getwrd(); 50 tree = getwrd(); 51 table = tabtab[getwrd()]; 52 line = getwrd(); 53 while(c--) 54 *sp++ = getwrd(); 55 rcexpr(tree, table, 0); 56 } else 57 putchar(c); 58 } 59 flush(); 60 exit(nerror!=0); 61 } 62 63 match(tree, table, nreg) 64 int tree[], table[]; { 65 extern opdope[], cctab, maprel; 66 int op, d1, d2, t1, t2, p1[], p2[], dope, cctab[]; 67 int maprel[]; 68 char mp[]; 69 70 if (tree==0) 71 return(0); 72 op = *tree; 73 if (op>=29) /* if not leaf */ 74 p1 = tree[3]; 75 else 76 p1 = tree; 77 t1 = p1[1]; 78 d1 = dcalc(p1, nreg); 79 if (((dope=opdope[op])&01)!=0) { /* binary? */ 80 p2 = tree[4]; 81 t2 = p2[1]; 82 d2 = dcalc(p2, nreg); 83 if (d2>d1 & (dope&0100)!=0) /* commute? */ 84 if (table!=cctab | (op!=47&op!=48)) { /* commute? */ 85 if ((dope&04)!=0) /* relation? */ 86 *tree = op = maprel[op-60]; 87 dope = t1; 88 t1 = t2; 89 t2 = dope; 90 dope = p1; 91 tree[3] = p1 = p2; 92 tree[4] = p2 = dope; 93 dope = d1; 94 d1 = d2; 95 d2 = dope; 96 dope = t1; 97 t1 = t2; 98 t2 = dope; 99 } 100 } 101 while(*table) { 102 if (*table++ == op) goto foundop; 103 table++; 104 } 105 return(0); 106 foundop: 107 table = *table; 108 nxtry: 109 mp = table; 110 if (*mp == 0) 111 return(0); 112 if (d1 > (*mp&077) | (*mp>=0100)&(*p1!=36)) 113 goto notyet; 114 if (notcompat(t1, mp[1])) 115 goto notyet; 116 if ((opdope[op]&01)!=0 & p2!=0) { 117 if (d2 > (mp[2]&077) | (mp[2]>=0100)&(*p2!=36)) 118 goto notyet; 119 if (notcompat(t2,mp[3])) 120 goto notyet; 121 } 122 now: 123 return(table[2]); 124 notyet: 125 table = table+3; 126 goto nxtry; 127 } 128 129 rcexpr(tree, table, reg) 130 int tree[]; { 131 extern cexpr, regtab, cctab, sptab, printf, error; 132 extern jumpc, cbranch; 133 int r, modf; 134 135 if(tree==0) 136 return(0); 137 if(*tree == 103 | *tree==104) { 138 (*tree==103?jumpc:cbranch)(tree[1],tree[2],tree[3],0); 139 return(0); 140 } 141 modf = isfloat(tree)? 'f':0; 142 if (*tree == 110) { /* force r0 */ 143 if((r=rcexpr(tree[3], table, reg)) != 0) 144 printf("mov%c r%d,r0\n", modf, r); 145 return(0); 146 } 147 if ((r=cexpr(tree, table, reg))>=0) 148 return(r); 149 if (table!=regtab) 150 if((r=cexpr(tree, regtab, reg))>=0) { 151 if (table==sptab) 152 printf("mov%c r%d,-(sp)\n", modf, r); 153 if (table==cctab) { 154 if (modf=='f') 155 printf("cfcc\n"); 156 printf("tst%c r%d\n", modf, r); 157 } 158 return(0); 159 } 160 error("No match for op %d", *tree); 161 } 162 163 cexpr(tree, table, reg) 164 int tree[][], table[]; { 165 extern match, nreg, printf, pname, putchar, regtab; 166 extern sptab, cctab, rcexpr, prins, rlength, popstk; 167 extern collcon, isn, label, branch, cbranch; 168 extern maprel[]; 169 int p1[], p2[], c, r, p[], otable[], ctable[], regtab[], cctab[]; 170 int sptab[]; 171 char string[], match[]; 172 int reg1, rreg; 173 174 if ((c = *tree)==100) { /* call */ 175 p1 = tree[3]; 176 p2 = tree[4]; 177 r = 0; 178 if(*p2) { 179 while (*p2==9) { /* comma */ 180 rcexpr(p2[4], sptab, 0); 181 r =+ arlength((p=p2[4])[1]); 182 p2 = p2[3]; 183 } 184 rcexpr(p2, sptab, 0); 185 r =+ arlength(p2[1]); 186 } 187 *tree = 101; 188 tree[2] = r; /* save arg length */ 189 } 190 if(c==90) { /* ? */ 191 cbranch(tree[3], c=isn++, 0, reg); 192 rcexpr(tree[4][3], table, reg); 193 branch(r=isn++, 0); 194 label(c); 195 reg = rcexpr(tree[4][4], table, reg); 196 label(r); 197 goto retrn; 198 } 199 reg = oddreg(tree, reg); 200 reg1 = reg+1; 201 if ((string=match(tree, table, nreg-reg))==0) 202 return(-1); 203 p1 = tree[3]; 204 p2 = tree[4]; 205 loop: 206 switch(c = *string++) { 207 208 case '\0': 209 p = tree; 210 if (*p==101) { 211 if (p[2]>0) 212 popstk(p[2]); 213 reg = 0; 214 } 215 retrn: 216 c = isfloat(tree); 217 if (table==cctab & c) 218 printf("cfcc\n"); 219 if (!c) 220 if ((c = *tree)==43 | c==73) 221 reg--; 222 return(reg); 223 224 /* A1 */ 225 case 'A': 226 p = tree[3]; 227 goto adr; 228 229 /* A2 */ 230 case 'B': 231 p = tree[4]; 232 goto adr; 233 234 /* A */ 235 case 'O': 236 p = tree; 237 adr: 238 pname(p); 239 goto loop; 240 241 /* I */ 242 case 'M': 243 if ((c = *string)=='\'') 244 string++; else 245 c = 0; 246 prins(*tree, c); 247 goto loop; 248 249 /* B1 */ 250 case 'C': 251 if ((c = *tree)<28) 252 p = tree; 253 else 254 p = tree[3]; 255 goto pbyte; 256 257 /* BF */ 258 case 'P': 259 p = tree; 260 goto pb1; 261 262 /* B2 */ 263 case 'D': 264 p = tree[4]; 265 pbyte: 266 if (p[1]==1) /* char type? */ 267 putchar('b'); 268 pb1: 269 if (isfloat(p)) 270 putchar('f'); 271 goto loop; 272 273 /* BE */ 274 case 'L': 275 if (tree[3][1]==1 | tree[4][1]==1) 276 putchar('b'); 277 p = tree; 278 goto pb1; 279 280 /* C1 */ 281 case 'E': 282 p = p1[3]; 283 goto const; 284 285 /* C2 */ 286 case 'F': 287 p = p2[3]; 288 const: 289 printf("%o", p); 290 goto loop; 291 292 /* F */ 293 case 'G': 294 p = p1; 295 goto subtre; 296 297 /* S */ 298 case 'K': 299 p = p2; 300 goto subtre; 301 302 /* H */ 303 case 'H': 304 p = tree; 305 306 subtre: 307 ctable = regtab; 308 r = reg; 309 c = *string++ - 'A'; 310 if ((c&02)!=0) 311 ctable = sptab; 312 if ((c&04)!=0) 313 ctable = cctab; 314 if((c&010)!=0) 315 r = reg1; 316 if((c&01)!=0) 317 if(*p==36) { 318 p = p[3]; 319 if(collcon(p) & ctable!=sptab) 320 p = p[3]; 321 } 322 rreg = rcexpr(p, ctable, r); 323 if (rreg==r | ctable!=regtab) 324 goto loop; 325 if (string[-2]=='G') /* left operand */ 326 if (oddreg(tree, 0)==1) { 327 printf("mov r%d,r%d\n", rreg, r); 328 goto loop; 329 } 330 if (r==reg) { 331 reg = rreg; 332 reg1 = rreg+1; 333 } else 334 reg1 = rreg; 335 goto loop; 336 337 /* R */ 338 case 'I': 339 r = reg; 340 if (*string=='-') { 341 string++; 342 r--; 343 } 344 goto preg; 345 346 /* R1 */ 347 case 'J': 348 r = reg1; 349 preg: 350 if (r>=5) 351 error("Register overflow: simplify expression"); 352 printf("r%d", r); 353 goto loop; 354 355 case '#': 356 p = p1[3]; 357 goto nmbr; 358 359 case '"': 360 p = p2[3]; 361 goto nmbr; 362 363 case '~': 364 p = tree[3]; 365 366 nmbr: 367 if(collcon(p)) { 368 if (*p==41) /* - */ 369 putchar('-'); 370 switch (*(p = p[4])) { 371 372 case 21: /* number */ 373 if (p[3]) 374 printf("%d.", p[3]); 375 break; 376 377 case 35: /* & name */ 378 pname(p[3]); 379 break; 380 381 } 382 } 383 goto loop; 384 385 /* V */ 386 case 'V': 387 tree[0] = maprel[(c=tree[0])-60]; 388 goto loop; 389 390 /* Z */ 391 case 'Z': 392 printf("$%o", p1[5]+p1[4]); 393 goto loop; 394 395 case '^': /* for ++ -- */ 396 printf("%o", tree[4]); 397 goto loop; 398 } 399 putchar(c); 400 goto loop; 401 } 402 403 pname(p) 404 int p[][]; { 405 char np[]; 406 int i; 407 408 loop: 409 switch(*p) { 410 411 case 21: /* const */ 412 printf("$%o", p[3]); 413 return; 414 415 case 23: /* float const */ 416 printf("L%d", p[3]); 417 return; 418 419 casename: 420 case 20: /* name */ 421 if (i=p[4]) 422 printf("%d.+", i); 423 switch(p[3]) { 424 425 case 5: /* auto, param */ 426 printf("%d.(r5)", p[5]); 427 return; 428 429 /* extern */ 430 case 6: 431 printf("%p", &p[5]); 432 return; 433 434 case 4: 435 error("Illegal structure reference"); 436 printf("$0"); 437 return; 438 439 } 440 printf("L%d", p[5]); 441 return; 442 443 case 35: /* & */ 444 putchar('$'); 445 p = p[3]; 446 goto loop; 447 448 case 36: /* * */ 449 putchar('*'); 450 p = p[3]; 451 goto loop; 452 453 } 454 error("pname called illegally"); 455 } 456 457 dcalc(p, nreg) 458 int p[]; { 459 int op, t, p1[], p2[]; 460 461 if (p==0) 462 return(0); 463 op = *p; 464 switch (op) { 465 466 case 20: /* name */ 467 case 35: /* & (non-automatic) */ 468 return(12); 469 470 case 21: /* short constant */ 471 return(p[3]==0? 4:8); 472 473 case 23: /* float const */ 474 return(p[3]==0? 4:12); 475 476 case 36: /* * */ 477 p1 = p[3]; 478 if (*p1==20) /* name or offset name */ 479 return(12); 480 } 481 482 def: 483 return(p[2]<=nreg? 20: 24); 484 } 485 486 notcompat(at, st) { 487 488 if (st==0) /* word, byte */ 489 return(at>1 & at<=07); 490 if (st==1) /* word */ 491 return(at>0 & at<=07); 492 st =- 2; 493 if ((at&077740) != 0) 494 at = 020; /* *int for **stuff */ 495 if ((at&077770) != 0) 496 at = at&07 | 020; 497 if (st==2 & at==3) 498 at = 2; 499 return(st != at); 500 } 501 502 prins(op, c) { 503 extern instab[], printf; 504 int insp[]; 505 506 insp = instab; 507 while(*insp) { 508 if (*insp++ == op) { 509 if ((c = insp[c!=0])==0) 510 goto err; 511 printf("%s", c); 512 return; 513 } else 514 insp = insp + 2; 515 } 516 err: 517 error("No match' for op %d", op); 518 } 519 520 collcon(p) 521 int p[]; { 522 int p1[], t[]; 523 524 if(*p==40 | *p==41) { 525 if(*(p1=p[4])==21) { /* number */ 526 return(1); 527 } 528 if (*p1==35) 529 return(1); 530 if (*(p1=p[3])==35) { 531 p1 = p[3]; 532 p[3] = p[4]; 533 p[4] = p1; 534 return(1); 535 } 536 } 537 return(0); 538 } 539 540 isfloat(t) 541 int t[]; 542 { 543 extern opdope[]; 544 int rt; 545 546 if ((opdope[t[0]]&04)!=0) /* relational */ 547 t = t[3]; 548 if ((rt=t[1])>=2 & rt<=3) 549 return(rt); 550 return(0); 551 } 552 553 nreg 3; 554 isn 10000; 555 namsiz 8; 556 line; 557 tmpfil; 558 nerror; 559 560 oddreg(t, reg) 561 int t[]; 562 { 563 if (!isfloat(t)) 564 switch(*t) { 565 case 43: /* / */ 566 case 44: /* % */ 567 case 73: /* =/ */ 568 case 74: /* =% */ 569 reg++; 570 571 case 42: /* * */ 572 case 72: /* =* */ 573 return(reg|1); 574 } 575 return(reg); 576 } 577 578 arlength(t) 579 { 580 int arl; 581 582 if ((arl=rlength(t)) == 4) 583 return(8); 584 return(arl); 585 } 586 587 maprel[] 60, 61, 64, 65, 62, 63, 68, 69, 66, 67; 588