1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 #include <bio.h> 5 #include "../6c/6.out.h" 6 #include "a.h" 7 #include "y.tab.h" 8 9 void 10 main(int argc, char *argv[]) 11 { 12 char ofile[100], incfile[20], *p; 13 int nout, nproc, status, i, c, of; 14 15 thechar = '6'; 16 thestring = "960"; 17 memset(debug, 0, sizeof(debug)); 18 cinit(); 19 outfile = 0; 20 include[ninclude++] = "."; 21 ARGBEGIN { 22 default: 23 c = ARGC(); 24 if(c >= 0 || c < sizeof(debug)) 25 debug[c] = 1; 26 break; 27 28 case 'o': 29 outfile = ARGF(); 30 break; 31 32 case 'D': 33 p = ARGF(); 34 if(p) 35 Dlist[nDlist++] = p; 36 break; 37 38 case 'I': 39 p = ARGF(); 40 if(p) 41 include[ninclude++] = p; 42 break; 43 } ARGEND 44 if(*argv == 0) { 45 print("usage: %ca [-options] file.s\n", thechar); 46 errorexit(); 47 } 48 nproc = 3; 49 if(p = getenv("NPROC")) 50 nproc = atol(p); 51 if(argc > 1) { 52 c = 0; 53 nout = 0; 54 for(;;) { 55 while(nout < nproc && argc > 0) { 56 i = fork(); 57 if(i < 0) { 58 i = mywait(&status); 59 if(i < 0) 60 errorexit(); 61 if(status) 62 c++; 63 nout--; 64 continue; 65 } 66 if(i == 0) { 67 print("%s:\n", *argv); 68 goto child; 69 } 70 nout++; 71 argc--; 72 argv++; 73 } 74 i = mywait(&status); 75 if(i < 0) { 76 if(c) 77 errorexit(); 78 exits(0); 79 } 80 if(status) 81 c++; 82 nout--; 83 } 84 } 85 86 child: 87 strcpy(ofile, *argv); 88 if(p = strrchr(ofile, '/')) { 89 include[0] = ofile; 90 *p++ = 0; 91 } else 92 p = ofile; 93 if(outfile == 0) { 94 outfile = p; 95 if(p = strrchr(outfile, '.')) 96 if(p[1] == 's' && p[2] == 0) 97 p[0] = 0; 98 p = strrchr(outfile, 0); 99 p[0] = '.'; 100 p[1] = thechar; 101 p[2] = 0; 102 } 103 if(unix()) { 104 strcpy(incfile, "/usr/%include"); 105 p = strrchr(incfile, '%'); 106 if(p) 107 *p = thechar; 108 } else { 109 strcpy(incfile, "/"); 110 strcat(incfile, thestring); 111 strcat(incfile, "/include"); 112 } 113 include[ninclude++] = incfile; 114 if(p = getenv("INCLUDE")) 115 include[ninclude-1] = p; /* */ 116 of = mycreat(outfile, 0664); 117 if(of < 0) { 118 yyerror("%ca: cannot create %s", thechar, outfile); 119 errorexit(); 120 } 121 Binit(&obuf, of, OWRITE); 122 123 pass = 1; 124 pinit(*argv); 125 for(i=0; i<nDlist; i++) 126 dodefine(Dlist[i]); 127 yyparse(); 128 if(nerrors) { 129 cclean(); 130 errorexit(); 131 } 132 133 pass = 2; 134 outhist(); 135 pinit(*argv); 136 for(i=0; i<nDlist; i++) 137 dodefine(Dlist[i]); 138 yyparse(); 139 cclean(); 140 if(nerrors) 141 errorexit(); 142 exits(0); 143 } 144 145 struct 146 { 147 char *name; 148 ushort type; 149 ushort value; 150 } itab[] = 151 { 152 "SP", LSP, D_AUTO, 153 "SB", LSB, D_EXTERN, 154 "FP", LFP, D_PARAM, 155 "PC", LPC, D_BRANCH, 156 157 "R0", LRREG, D_R0+0, /* 960 pfp, r0 */ 158 "R1", LRREG, D_R0+1, /* 960 sp, r1 */ 159 "R2", LRREG, D_R0+2, /* 960 rip, r2 */ 160 "R3", LRREG, D_R0+3, 161 "R4", LRREG, D_R0+4, 162 "R5", LRREG, D_R0+5, 163 "R6", LRREG, D_R0+6, 164 "R7", LRREG, D_R0+7, 165 "R8", LRREG, D_R0+8, 166 "R9", LRREG, D_R0+9, 167 "R10", LRREG, D_R0+10, 168 "R11", LRREG, D_R0+11, 169 "R12", LRREG, D_R0+12, 170 "R13", LRREG, D_R0+13, 171 "R14", LRREG, D_R0+14, 172 "R15", LRREG, D_R0+15, 173 "R16", LRREG, D_R0+16, /* g0 */ 174 "R17", LRREG, D_R0+17, 175 "R18", LRREG, D_R0+18, 176 "R19", LRREG, D_R0+19, 177 "R20", LRREG, D_R0+20, 178 "R21", LRREG, D_R0+21, 179 "R22", LRREG, D_R0+22, 180 "R23", LRREG, D_R0+23, 181 "R24", LRREG, D_R0+24, 182 "R25", LRREG, D_R0+25, 183 "R26", LRREG, D_R0+26, 184 "R27", LRREG, D_R0+27, 185 "R28", LRREG, D_R0+28, /* static register */ 186 "R29", LRREG, D_R0+29, /* stack register */ 187 "R30", LRREG, D_R0+30, /* link register */ 188 "R31", LRREG, D_R0+31, /* 960 fp, g15 */ 189 190 "DATA", LTYPE1, ADATA, 191 192 "ADJSP", LTYPEX, AADJSP, 193 "SYSCALL", LTYPEX, ASYSCALL, 194 "CALL", LTYPEX, ACALL, 195 "CALLS", LTYPEX, ACALLS, 196 197 "GLOBL", LTYPEB, AGLOBL, 198 "TEXT", LTYPEB, ATEXT, 199 "LONG", LTYPES, ALONG, 200 "NOP", LTYPES, ANOP, 201 "RTS", LTYPEB, ARTS, 202 203 "ADDC", LTYPEB, AADDC, 204 "ADDI", LTYPEB, AADDI, 205 "ADDO", LTYPEB, AADDO, 206 "ALTERBIT", LTYPEB, AALTERBIT, 207 "AND", LTYPEB, AAND, 208 "ANDNOT", LTYPEB, AANDNOT, 209 "ATADD", LTYPEB, AATADD, 210 "ATMOD", LTYPEB, AATMOD, 211 "B", LTYPED, AB, 212 "BAL", LTYPED, ABAL, 213 "BBC", LTYPED, ABBC, 214 "BBS", LTYPED, ABBS, 215 "BE", LTYPED, ABE, 216 "BG", LTYPED, ABG, 217 "BGE", LTYPED, ABGE, 218 "BL", LTYPED, ABL, 219 "BLE", LTYPED, ABLE, 220 "BNE", LTYPED, ABNE, 221 "BNO", LTYPED, ABNO, 222 "BO", LTYPED, ABO, 223 "CHKBIT", LTYPEB, ACHKBIT, 224 "CLRBIT", LTYPEB, ACLRBIT, 225 "CMPDECI", LTYPEB, ACMPDECI, 226 "CMPDECO", LTYPEB, ACMPDECO, 227 "CMPI", LTYPEB, ACMPI, 228 "CMPIBE", LTYPEB, ACMPIBE, 229 "CMPIBG", LTYPEB, ACMPIBG, 230 "CMPIBGE", LTYPEB, ACMPIBGE, 231 "CMPIBL", LTYPEB, ACMPIBL, 232 "CMPIBLE", LTYPEB, ACMPIBLE, 233 "CMPIBNE", LTYPEB, ACMPIBNE, 234 "CMPIBNO", LTYPEB, ACMPIBNO, 235 "CMPIBO", LTYPEB, ACMPIBO, 236 "CMPINCI", LTYPEB, ACMPINCI, 237 "CMPINCO", LTYPEB, ACMPINCO, 238 "CMPO", LTYPEB, ACMPO, 239 "CMPOBE", LTYPEB, ACMPOBE, 240 "CMPOBG", LTYPEB, ACMPOBG, 241 "CMPOBGE", LTYPEB, ACMPOBGE, 242 "CMPOBL", LTYPEB, ACMPOBL, 243 "CMPOBLE", LTYPEB, ACMPOBLE, 244 "CMPOBNE", LTYPEB, ACMPOBNE, 245 "CONCMPI", LTYPEB, ACONCMPI, 246 "CONCMPO", LTYPEB, ACONCMPO, 247 "DADDC", LTYPEB, ADADDC, 248 "DIVI", LTYPEB, ADIVI, 249 "DIVO", LTYPEB, ADIVO, 250 "DMOVT", LTYPEB, ADMOVT, 251 "DSUBC", LTYPEB, ADSUBC, 252 "EDIV", LTYPEB, AEDIV, 253 "EMUL", LTYPEB, AEMUL, 254 "EXTRACT", LTYPEB, AEXTRACT, 255 "FAULTE", LTYPEB, AFAULTE, 256 "FAULTG", LTYPEB, AFAULTG, 257 "FAULTGE", LTYPEB, AFAULTGE, 258 "FAULTL", LTYPEB, AFAULTL, 259 "FAULTLE", LTYPEB, AFAULTLE, 260 "FAULTNE", LTYPEB, AFAULTNE, 261 "FAULTNO", LTYPEB, AFAULTNO, 262 "FAULTO", LTYPEB, AFAULTO, 263 "FLUSHREG", LTYPEB, AFLUSHREG, 264 "FMARK", LTYPEB, AFMARK, 265 "MARK", LTYPEB, AMARK, 266 "MODAC", LTYPEB, AMODAC, 267 "MODI", LTYPEB, AMODI, 268 "MODIFY", LTYPEB, AMODIFY, 269 "MODPC", LTYPEB, AMODPC, 270 "MODTC", LTYPEB, AMODTC, 271 "MOV", LTYPEB, AMOV, 272 "MOVA", LTYPEB, AMOVA, 273 "MOVIB", LTYPEB, AMOVIB, 274 "MOVIS", LTYPEB, AMOVIS, 275 "MOVOB", LTYPEB, AMOVOB, 276 "MOVOS", LTYPEB, AMOVOS, 277 "MOVQ", LTYPEB, AMOVQ, 278 "MOVT", LTYPEB, AMOVT, 279 "MOVV", LTYPEB, AMOVV, 280 "MULI", LTYPEB, AMULI, 281 "MULO", LTYPEB, AMULO, 282 "NAND", LTYPEB, ANAND, 283 "NOR", LTYPEB, ANOR, 284 "NOT", LTYPEB, ANOT, 285 "NOTAND", LTYPEB, ANOTAND, 286 "NOTBIT", LTYPEB, ANOTBIT, 287 "NOTOR", LTYPEB, ANOTOR, 288 "OR", LTYPEB, AOR, 289 "ORNOT", LTYPEB, AORNOT, 290 "REMI", LTYPEB, AREMI, 291 "REMO", LTYPEB, AREMO, 292 "RET", LTYPEB, ARET, 293 "ROTATE", LTYPEB, AROTATE, 294 "SCANBIT", LTYPEB, ASCANBIT, 295 "SCANBYTE", LTYPEB, ASCANBYTE, 296 "SETBIT", LTYPEB, ASETBIT, 297 "SHLI", LTYPEB, ASHLI, 298 "SHLO", LTYPEB, ASHLO, 299 "SHRDI", LTYPEB, ASHRDI, 300 "SHRI", LTYPEB, ASHRI, 301 "SHRO", LTYPEB, ASHRO, 302 "SPANBIT", LTYPEB, ASPANBIT, 303 "SUBC", LTYPEB, ASUBC, 304 "SUBI", LTYPEB, ASUBI, 305 "SUBO", LTYPEB, ASUBO, 306 "SYNCF", LTYPEB, ASYNCF, 307 "SYNMOV", LTYPEB, ASYNMOV, 308 "SYNMOVQ", LTYPEB, ASYNMOVQ, 309 "SYNMOVV", LTYPEB, ASYNMOVV, 310 "SYSCTL", LTYPEB, ASYSCTL, 311 "TESTE", LTYPED, ATESTE, 312 "TESTG", LTYPED, ATESTG, 313 "TESTGE", LTYPED, ATESTGE, 314 "TESTL", LTYPED, ATESTL, 315 "TESTLE", LTYPED, ATESTLE, 316 "TESTNE", LTYPED, ATESTNE, 317 "TESTNO", LTYPED, ATESTNO, 318 "TESTO", LTYPED, ATESTO, 319 "XNOR", LTYPEB, AXNOR, 320 "XOR", LTYPEB, AXOR, 321 322 0 323 }; 324 325 void 326 cinit(void) 327 { 328 Sym *s; 329 int i; 330 331 nullgen.sym = S; 332 nullgen.offset = 0; 333 if(FPCHIP) 334 nullgen.dval = 0; 335 for(i=0; i<sizeof(nullgen.sval); i++) 336 nullgen.sval[i] = 0; 337 nullgen.type = D_NONE; 338 nullgen.index = D_NONE; 339 nullgen.scale = 0; 340 341 nerrors = 0; 342 iostack = I; 343 iofree = I; 344 peekc = IGN; 345 nhunk = 0; 346 for(i=0; i<NHASH; i++) 347 hash[i] = S; 348 for(i=0; itab[i].name; i++) { 349 s = slookup(itab[i].name); 350 if(s->type != LNAME) 351 yyerror("double initialization %s", itab[i].name); 352 s->type = itab[i].type; 353 s->value = itab[i].value; 354 } 355 356 ALLOCN(pathname, 0, 100); 357 if(getwd(pathname, 99) == 0) { 358 ALLOCN(pathname, 100, 900); 359 if(getwd(pathname, 999) == 0) 360 strcpy(pathname, "/???"); 361 } 362 } 363 364 void 365 checkscale(int scale) 366 { 367 368 switch(scale) { 369 case 1: 370 case 2: 371 case 4: 372 case 8: 373 case 16: 374 return; 375 } 376 yyerror("scale must be 1<<[01234]: %d", scale); 377 } 378 379 void 380 syminit(Sym *s) 381 { 382 383 s->type = LNAME; 384 s->value = 0; 385 } 386 387 void 388 cclean(void) 389 { 390 Gen2 g2; 391 392 g2.from = nullgen; 393 g2.to = nullgen; 394 outcode(AEND, &g2); 395 Bflush(&obuf); 396 } 397 398 void 399 zname(char *n, int t, int s) 400 { 401 402 Bputc(&obuf, ANAME); /* as */ 403 Bputc(&obuf, t); /* type */ 404 Bputc(&obuf, s); /* sym */ 405 while(*n) { 406 Bputc(&obuf, *n); 407 n++; 408 } 409 Bputc(&obuf, 0); 410 } 411 412 void 413 zaddr(Gen *a, int s) 414 { 415 long l; 416 int i, t; 417 char *n; 418 Ieee e; 419 420 t = 0; 421 if(a->index != D_NONE || a->scale != 0) 422 t |= T_INDEX; 423 if(s != 0) 424 t |= T_SYM; 425 426 switch(a->type) { 427 default: 428 t |= T_TYPE; 429 case D_NONE: 430 if(a->offset != 0) 431 t |= T_OFFSET; 432 break; 433 case D_FCONST: 434 t |= T_FCONST; 435 break; 436 case D_SCONST: 437 t |= T_SCONST; 438 break; 439 } 440 Bputc(&obuf, t); 441 442 if(t & T_INDEX) { /* implies index, scale */ 443 Bputc(&obuf, a->index); 444 Bputc(&obuf, a->scale); 445 } 446 if(t & T_OFFSET) { /* implies offset */ 447 l = a->offset; 448 Bputc(&obuf, l); 449 Bputc(&obuf, l>>8); 450 Bputc(&obuf, l>>16); 451 Bputc(&obuf, l>>24); 452 } 453 if(t & T_SYM) /* implies sym */ 454 Bputc(&obuf, s); 455 if(t & T_FCONST) { 456 ieeedtod(&e, a->dval); 457 l = e.l; 458 Bputc(&obuf, l); 459 Bputc(&obuf, l>>8); 460 Bputc(&obuf, l>>16); 461 Bputc(&obuf, l>>24); 462 l = e.h; 463 Bputc(&obuf, l); 464 Bputc(&obuf, l>>8); 465 Bputc(&obuf, l>>16); 466 Bputc(&obuf, l>>24); 467 return; 468 } 469 if(t & T_SCONST) { 470 n = a->sval; 471 for(i=0; i<NSNAME; i++) { 472 Bputc(&obuf, *n); 473 n++; 474 } 475 return; 476 } 477 if(t & T_TYPE) 478 Bputc(&obuf, a->type); 479 } 480 481 void 482 outcode(int a, Gen2 *g2) 483 { 484 int sf, st, t; 485 Sym *s; 486 487 if(pass == 1) 488 goto out; 489 490 jackpot: 491 sf = 0; 492 s = g2->from.sym; 493 while(s != S) { 494 sf = s->sym; 495 if(sf < 0 || sf >= NSYM) 496 sf = 0; 497 t = g2->from.type; 498 if(h[sf].type == t) 499 if(h[sf].sym == s) 500 break; 501 zname(s->name, t, sym); 502 s->sym = sym; 503 h[sym].sym = s; 504 h[sym].type = t; 505 sf = sym; 506 sym++; 507 if(sym >= NSYM) 508 sym = 1; 509 break; 510 } 511 st = 0; 512 s = g2->to.sym; 513 while(s != S) { 514 st = s->sym; 515 if(st < 0 || st >= NSYM) 516 st = 0; 517 t = g2->to.type; 518 if(h[st].type == t) 519 if(h[st].sym == s) 520 break; 521 zname(s->name, t, sym); 522 s->sym = sym; 523 h[sym].sym = s; 524 h[sym].type = t; 525 st = sym; 526 sym++; 527 if(sym >= NSYM) 528 sym = 1; 529 if(st == sf) 530 goto jackpot; 531 break; 532 } 533 Bputc(&obuf, a); 534 Bputc(&obuf, lineno); 535 Bputc(&obuf, lineno>>8); 536 Bputc(&obuf, lineno>>16); 537 Bputc(&obuf, lineno>>24); 538 switch(t = g2->type) { 539 case D_NONE: 540 t = 0; /* 0 D_NONE */ 541 break; 542 543 default: 544 if(t < D_R0 || t >= D_R0+32) { 545 yyerror("bad type in outcode: %d", t); 546 t = D_R0; 547 } 548 t = (t - D_R0) + 1; /* 1-32 D_R0+ */ 549 break; 550 551 case D_CONST: 552 t = g2->offset; 553 if(t >= 32) { 554 yyerror("bad offset in outcode", t); 555 t = 0; 556 } 557 t = (t - 0) + 33; /* 33-64 D_CONST+ */ 558 break; 559 } 560 Bputc(&obuf, t); 561 zaddr(&g2->from, sf); 562 zaddr(&g2->to, st); 563 564 out: 565 if(a != AGLOBL && a != ADATA) 566 pc++; 567 } 568 569 void 570 outhist(void) 571 { 572 Gen g; 573 Hist *h; 574 char *p, *q, *op; 575 int n; 576 577 g = nullgen; 578 for(h = hist; h != H; h = h->link) { 579 p = h->name; 580 op = 0; 581 if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { 582 op = p; 583 p = pathname; 584 } 585 while(p) { 586 q = strchr(p, '/'); 587 if(q) { 588 n = q-p; 589 if(n == 0) 590 n = 1; /* leading "/" */ 591 q++; 592 } else { 593 n = strlen(p); 594 q = 0; 595 } 596 if(n) { 597 Bputc(&obuf, ANAME); 598 Bputc(&obuf, D_FILE); /* type */ 599 Bputc(&obuf, 1); /* sym */ 600 Bputc(&obuf, '<'); 601 Bwrite(&obuf, p, n); 602 Bputc(&obuf, 0); 603 } 604 p = q; 605 if(p == 0 && op) { 606 p = op; 607 op = 0; 608 } 609 } 610 g.offset = h->offset; 611 612 Bputc(&obuf, AHISTORY); 613 Bputc(&obuf, h->line); 614 Bputc(&obuf, h->line>>8); 615 Bputc(&obuf, h->line>>16); 616 Bputc(&obuf, h->line>>24); 617 Bputc(&obuf, 0); /* reg */ 618 zaddr(&nullgen, 0); 619 zaddr(&g, 0); 620 } 621 } 622 623 #include "../cc/lexbody" 624 #include "../cc/macbody" 625