1 #include <u.h> 2 #include <libc.h> 3 #include <ctype.h> 4 #include <bio.h> 5 #include "../qc/q.out.h" 6 #include "a.h" 7 #include "y.tab.h" 8 9 void 10 main(int argc, char *argv[]) 11 { 12 char *p; 13 int nout, nproc, status, i, c; 14 15 thechar = 'q'; 16 thestring = "power"; 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 setinclude(p); 41 break; 42 } ARGEND 43 if(*argv == 0) { 44 print("usage: %ca [-options] file.s\n", thechar); 45 errorexit(); 46 } 47 if(argc > 1 && systemtype(Windows)){ 48 print("can't assemble multiple files on windows\n"); 49 errorexit(); 50 } 51 if(argc > 1 && !systemtype(Windows)) { 52 nproc = 1; 53 if(p = getenv("NPROC")) 54 nproc = atol(p); /* */ 55 c = 0; 56 nout = 0; 57 for(;;) { 58 while(nout < nproc && argc > 0) { 59 i = myfork(); 60 if(i < 0) { 61 i = mywait(&status); 62 if(i < 0) 63 errorexit(); 64 if(status) 65 c++; 66 nout--; 67 continue; 68 } 69 if(i == 0) { 70 print("%s:\n", *argv); 71 if(assemble(*argv)) 72 errorexit(); 73 exits(0); 74 } 75 nout++; 76 argc--; 77 argv++; 78 } 79 i = mywait(&status); 80 if(i < 0) { 81 if(c) 82 errorexit(); 83 exits(0); 84 } 85 if(status) 86 c++; 87 nout--; 88 } 89 } 90 if(assemble(argv[0])) 91 errorexit(); 92 exits(0); 93 } 94 95 int 96 assemble(char *file) 97 { 98 char ofile[100], incfile[20], *p; 99 int i, of; 100 101 strcpy(ofile, file); 102 p = utfrrune(ofile, pathchar()); 103 if(p) { 104 include[0] = ofile; 105 *p++ = 0; 106 } else 107 p = ofile; 108 if(outfile == 0) { 109 outfile = p; 110 if(outfile){ 111 p = utfrrune(outfile, '.'); 112 if(p) 113 if(p[1] == 's' && p[2] == 0) 114 p[0] = 0; 115 p = utfrune(outfile, 0); 116 p[0] = '.'; 117 p[1] = thechar; 118 p[2] = 0; 119 } else 120 outfile = "/dev/null"; 121 } 122 p = getenv("INCLUDE"); 123 if(p) { 124 setinclude(p); 125 } else { 126 if(systemtype(Plan9)) { 127 sprint(incfile,"/%s/include", thestring); 128 setinclude(strdup(incfile)); 129 } 130 } 131 132 of = mycreat(outfile, 0664); 133 if(of < 0) { 134 yyerror("%ca: cannot create %s", thechar, outfile); 135 errorexit(); 136 } 137 Binit(&obuf, of, OWRITE); 138 139 pass = 1; 140 pinit(file); 141 for(i=0; i<nDlist; i++) 142 dodefine(Dlist[i]); 143 yyparse(); 144 if(nerrors) { 145 cclean(); 146 return nerrors; 147 } 148 149 pass = 2; 150 outhist(); 151 pinit(file); 152 for(i=0; i<nDlist; i++) 153 dodefine(Dlist[i]); 154 yyparse(); 155 cclean(); 156 return nerrors; 157 } 158 159 struct 160 { 161 char *name; 162 ushort type; 163 ushort value; 164 } itab[] = 165 { 166 "SP", LSP, D_AUTO, 167 "SB", LSB, D_EXTERN, 168 "FP", LFP, D_PARAM, 169 "PC", LPC, D_BRANCH, 170 171 "LR", LLR, D_LR, 172 "CTR", LCTR, D_CTR, 173 174 "XER", LSPREG, D_XER, 175 "MSR", LMSR, D_MSR, 176 "FPSCR", LFPSCR, D_FPSCR, 177 "SPR", LSPR, D_SPR, 178 179 "SEG", LSEG, D_SREG, 180 181 "CR", LCR, 0, 182 "CR0", LCREG, 0, 183 "CR1", LCREG, 1, 184 "CR2", LCREG, 2, 185 "CR3", LCREG, 3, 186 "CR4", LCREG, 4, 187 "CR5", LCREG, 5, 188 "CR6", LCREG, 6, 189 "CR7", LCREG, 7, 190 191 "R", LR, 0, 192 "R0", LREG, 0, 193 "R1", LREG, 1, 194 "R2", LREG, 2, 195 "R3", LREG, 3, 196 "R4", LREG, 4, 197 "R5", LREG, 5, 198 "R6", LREG, 6, 199 "R7", LREG, 7, 200 "R8", LREG, 8, 201 "R9", LREG, 9, 202 "R10", LREG, 10, 203 "R11", LREG, 11, 204 "R12", LREG, 12, 205 "R13", LREG, 13, 206 "R14", LREG, 14, 207 "R15", LREG, 15, 208 "R16", LREG, 16, 209 "R17", LREG, 17, 210 "R18", LREG, 18, 211 "R19", LREG, 19, 212 "R20", LREG, 20, 213 "R21", LREG, 21, 214 "R22", LREG, 22, 215 "R23", LREG, 23, 216 "R24", LREG, 24, 217 "R25", LREG, 25, 218 "R26", LREG, 26, 219 "R27", LREG, 27, 220 "R28", LREG, 28, 221 "R29", LREG, 29, 222 "R30", LREG, 30, 223 "R31", LREG, 31, 224 225 "F", LF, 0, 226 "F0", LFREG, 0, 227 "F1", LFREG, 1, 228 "F2", LFREG, 2, 229 "F3", LFREG, 3, 230 "F4", LFREG, 4, 231 "F5", LFREG, 5, 232 "F6", LFREG, 6, 233 "F7", LFREG, 7, 234 "F8", LFREG, 8, 235 "F9", LFREG, 9, 236 "F10", LFREG, 10, 237 "F11", LFREG, 11, 238 "F12", LFREG, 12, 239 "F13", LFREG, 13, 240 "F14", LFREG, 14, 241 "F15", LFREG, 15, 242 "F16", LFREG, 16, 243 "F17", LFREG, 17, 244 "F18", LFREG, 18, 245 "F19", LFREG, 19, 246 "F20", LFREG, 20, 247 "F21", LFREG, 21, 248 "F22", LFREG, 22, 249 "F23", LFREG, 23, 250 "F24", LFREG, 24, 251 "F25", LFREG, 25, 252 "F26", LFREG, 26, 253 "F27", LFREG, 27, 254 "F28", LFREG, 28, 255 "F29", LFREG, 29, 256 "F30", LFREG, 30, 257 "F31", LFREG, 31, 258 259 "CREQV", LCROP, ACREQV, 260 "CRXOR", LCROP, ACRXOR, 261 "CRAND", LCROP, ACRAND, 262 "CROR", LCROP, ACROR, 263 "CRANDN", LCROP, ACRANDN, 264 "CRORN", LCROP, ACRORN, 265 "CRNAND", LCROP, ACRNAND, 266 "CRNOR", LCROP, ACRNOR, 267 268 "ADD", LADDW, AADD, 269 "ADDV", LADDW, AADDV, 270 "ADDCC", LADDW, AADDCC, 271 "ADDVCC", LADDW, AADDVCC, 272 "ADDC", LADDW, AADDC, 273 "ADDCV", LADDW, AADDCV, 274 "ADDCCC", LADDW, AADDCCC, 275 "ADDCVCC", LADDW, AADDCVCC, 276 "ADDE", LLOGW, AADDE, 277 "ADDEV", LLOGW, AADDEV, 278 "ADDECC", LLOGW, AADDECC, 279 "ADDEVCC", LLOGW, AADDEVCC, 280 281 "ADDME", LABS, AADDME, 282 "ADDMEV", LABS, AADDMEV, 283 "ADDMECC", LABS, AADDMECC, 284 "ADDMEVCC", LABS, AADDMEVCC, 285 "ADDZE", LABS, AADDZE, 286 "ADDZEV", LABS, AADDZEV, 287 "ADDZECC", LABS, AADDZECC, 288 "ADDZEVCC", LABS, AADDZEVCC, 289 290 "SUB", LADDW, ASUB, 291 "SUBV", LADDW, ASUBV, 292 "SUBCC", LADDW, ASUBCC, 293 "SUBVCC", LADDW, ASUBVCC, 294 "SUBE", LLOGW, ASUBE, 295 "SUBECC", LLOGW, ASUBECC, 296 "SUBEV", LLOGW, ASUBEV, 297 "SUBEVCC", LLOGW, ASUBEVCC, 298 "SUBC", LADDW, ASUBC, 299 "SUBCCC", LADDW, ASUBCCC, 300 "SUBCV", LADDW, ASUBCV, 301 "SUBCVCC", LADDW, ASUBCVCC, 302 303 "SUBME", LABS, ASUBME, 304 "SUBMEV", LABS, ASUBMEV, 305 "SUBMECC", LABS, ASUBMECC, 306 "SUBMEVCC", LABS, ASUBMEVCC, 307 "SUBZE", LABS, ASUBZE, 308 "SUBZEV", LABS, ASUBZEV, 309 "SUBZECC", LABS, ASUBZECC, 310 "SUBZEVCC", LABS, ASUBZEVCC, 311 312 "AND", LADDW, AAND, 313 "ANDCC", LADDW, AANDCC, /* includes andil & andiu */ 314 "ANDN", LLOGW, AANDN, 315 "ANDNCC", LLOGW, AANDNCC, 316 "EQV", LLOGW, AEQV, 317 "EQVCC", LLOGW, AEQVCC, 318 "NAND", LLOGW, ANAND, 319 "NANDCC", LLOGW, ANANDCC, 320 "NOR", LLOGW, ANOR, 321 "NORCC", LLOGW, ANORCC, 322 "OR", LADDW, AOR, /* includes oril & oriu */ 323 "ORCC", LADDW, AORCC, 324 "ORN", LLOGW, AORN, 325 "ORNCC", LLOGW, AORNCC, 326 "XOR", LADDW, AXOR, /* includes xoril & xoriu */ 327 "XORCC", LLOGW, AXORCC, 328 329 "EXTSB", LABS, AEXTSB, 330 "EXTSBCC", LABS, AEXTSBCC, 331 "EXTSH", LABS, AEXTSH, 332 "EXTSHCC", LABS, AEXTSHCC, 333 334 "CNTLZW", LABS, ACNTLZW, 335 "CNTLZWCC", LABS, ACNTLZWCC, 336 337 "RLWMI", LRLWM, ARLWMI, 338 "RLWMICC", LRLWM, ARLWMICC, 339 "RLWNM", LRLWM, ARLWNM, 340 "RLWNMCC", LRLWM, ARLWNMCC, 341 342 "SLW", LSHW, ASLW, 343 "SLWCC", LSHW, ASLWCC, 344 "SRW", LSHW, ASRW, 345 "SRWCC", LSHW, ASRWCC, 346 "SRAW", LSHW, ASRAW, 347 "SRAWCC", LSHW, ASRAWCC, 348 349 "BR", LBRA, ABR, 350 "BC", LBRA, ABC, 351 "BCL", LBRA, ABC, 352 "BL", LBRA, ABL, 353 "BEQ", LBRA, ABEQ, 354 "BNE", LBRA, ABNE, 355 "BGT", LBRA, ABGT, 356 "BGE", LBRA, ABGE, 357 "BLT", LBRA, ABLT, 358 "BLE", LBRA, ABLE, 359 "BVC", LBRA, ABVC, 360 "BVS", LBRA, ABVS, 361 362 "CMP", LCMP, ACMP, 363 "CMPU", LCMP, ACMPU, 364 365 "DIVW", LLOGW, ADIVW, 366 "DIVWV", LLOGW, ADIVWV, 367 "DIVWCC", LLOGW, ADIVWCC, 368 "DIVWVCC", LLOGW, ADIVWVCC, 369 "DIVWU", LLOGW, ADIVWU, 370 "DIVWUV", LLOGW, ADIVWUV, 371 "DIVWUCC", LLOGW, ADIVWUCC, 372 "DIVWUVCC", LLOGW, ADIVWUVCC, 373 374 "FABS", LFCONV, AFABS, 375 "FABSCC", LFCONV, AFABSCC, 376 "FNEG", LFCONV, AFNEG, 377 "FNEGCC", LFCONV, AFNEGCC, 378 "FNABS", LFCONV, AFNABS, 379 "FNABSCC", LFCONV, AFNABSCC, 380 381 "FADD", LFADD, AFADD, 382 "FADDCC", LFADD, AFADDCC, 383 "FSUB", LFADD, AFSUB, 384 "FSUBCC", LFADD, AFSUBCC, 385 "FMUL", LFADD, AFMUL, 386 "FMULCC", LFADD, AFMULCC, 387 "FDIV", LFADD, AFDIV, 388 "FDIVCC", LFADD, AFDIVCC, 389 "FRSP", LFCONV, AFRSP, 390 "FRSPCC", LFCONV, AFRSPCC, 391 392 "FMADD", LFMA, AFMADD, 393 "FMADDCC", LFMA, AFMADDCC, 394 "FMSUB", LFMA, AFMSUB, 395 "FMSUBCC", LFMA, AFMSUBCC, 396 "FNMADD", LFMA, AFNMADD, 397 "FNMADDCC", LFMA, AFNMADDCC, 398 "FNMSUB", LFMA, AFNMSUB, 399 "FNMSUBCC", LFMA, AFNMSUBCC, 400 "FMADDS", LFMA, AFMADDS, 401 "FMADDSCC", LFMA, AFMADDSCC, 402 "FMSUBS", LFMA, AFMSUBS, 403 "FMSUBSCC", LFMA, AFMSUBSCC, 404 "FNMADDS", LFMA, AFNMADDS, 405 "FNMADDSCC", LFMA, AFNMADDSCC, 406 "FNMSUBS", LFMA, AFNMSUBS, 407 "FNMSUBSCC", LFMA, AFNMSUBSCC, 408 409 "FCMPU", LFCMP, AFCMPU, 410 "FCMPO", LFCMP, AFCMPO, 411 "MTFSB0", LMTFSB, AMTFSB0, 412 "MTFSB1", LMTFSB, AMTFSB1, 413 414 "FMOVD", LFMOV, AFMOVD, 415 "FMOVS", LFMOV, AFMOVS, 416 "FMOVDCC", LFCONV, AFMOVDCC, /* fmr. */ 417 418 "GLOBL", LTEXT, AGLOBL, 419 420 "MOVB", LMOVB, AMOVB, 421 "MOVBZ", LMOVB, AMOVBZ, 422 "MOVBU", LMOVB, AMOVBU, 423 "MOVBZU", LMOVB, AMOVBZU, 424 "MOVH", LMOVB, AMOVH, 425 "MOVHZ", LMOVB, AMOVHZ, 426 "MOVHU", LMOVB, AMOVHU, 427 "MOVHZU", LMOVB, AMOVHZU, 428 "MOVHBR", LXMV, AMOVHBR, 429 "MOVWBR", LXMV, AMOVWBR, 430 "MOVW", LMOVW, AMOVW, 431 "MOVWU", LMOVW, AMOVWU, 432 "MOVMW", LMOVMW, AMOVMW, 433 "MOVFL", LMOVW, AMOVFL, 434 435 "MULLW", LADDW, AMULLW, /* includes multiply immediate 10-139 */ 436 "MULLWV", LLOGW, AMULLWV, 437 "MULLWCC", LLOGW, AMULLWCC, 438 "MULLWVCC", LLOGW, AMULLWVCC, 439 440 "MULHW", LLOGW, AMULHW, 441 "MULHWCC", LLOGW, AMULHWCC, 442 "MULHWU", LLOGW, AMULHWU, 443 "MULHWUCC", LLOGW, AMULHWUCC, 444 445 "NEG", LABS, ANEG, 446 "NEGV", LABS, ANEGV, 447 "NEGCC", LABS, ANEGCC, 448 "NEGVCC", LABS, ANEGVCC, 449 450 "NOP", LNOP, ANOP, /* ori 0,0,0 */ 451 "SYSCALL", LNOP, ASYSCALL, 452 453 "RETURN", LRETRN, ARETURN, 454 "RFI", LRETRN, ARFI, 455 456 "DATA", LDATA, ADATA, 457 "END", LEND, AEND, 458 "TEXT", LTEXT, ATEXT, 459 460 /* special instructions */ 461 "DCBF", LXOP, ADCBF, 462 "DCBI", LXOP, ADCBI, 463 "DCBST", LXOP, ADCBST, 464 "DCBT", LXOP, ADCBT, 465 "DCBTST", LXOP, ADCBTST, 466 "DCBZ", LXOP, ADCBZ, 467 "ICBI", LXOP, AICBI, 468 469 "ECIWX", LXLD, AECIWX, 470 "ECOWX", LXST, AECOWX, 471 "LWAR", LXLD, ALWAR, 472 "STWCCC", LXST, ASTWCCC, 473 "EIEIO", LRETRN, AEIEIO, 474 "TLBIE", LNOP, ATLBIE, 475 "LSW", LXLD, ALSW, 476 "STSW", LXST, ASTSW, 477 478 "ISYNC", LRETRN, AISYNC, 479 "SYNC", LRETRN, ASYNC, 480 /* "TW", LADDW, ATW,*/ 481 482 "WORD", LWORD, AWORD, 483 "SCHED", LSCHED, 0, 484 "NOSCHED", LSCHED, 0x80, 485 486 0 487 }; 488 489 void 490 cinit(void) 491 { 492 Sym *s; 493 int i; 494 495 nullgen.sym = S; 496 nullgen.offset = 0; 497 nullgen.type = D_NONE; 498 nullgen.name = D_NONE; 499 nullgen.reg = NREG; 500 nullgen.xreg = NREG; 501 if(FPCHIP) 502 nullgen.dval = 0; 503 for(i=0; i<sizeof(nullgen.sval); i++) 504 nullgen.sval[i] = 0; 505 506 nerrors = 0; 507 iostack = I; 508 iofree = I; 509 peekc = IGN; 510 nhunk = 0; 511 for(i=0; i<NHASH; i++) 512 hash[i] = S; 513 for(i=0; itab[i].name; i++) { 514 s = slookup(itab[i].name); 515 s->type = itab[i].type; 516 s->value = itab[i].value; 517 } 518 ALLOCN(pathname, 0, 100); 519 if(getwd(pathname, 99) == 0) { 520 ALLOCN(pathname, 100, 900); 521 if(getwd(pathname, 999) == 0) 522 strcpy(pathname, "/???"); 523 } 524 } 525 526 void 527 syminit(Sym *s) 528 { 529 530 s->type = LNAME; 531 s->value = 0; 532 } 533 534 void 535 cclean(void) 536 { 537 538 outcode(AEND, &nullgen, NREG, &nullgen); 539 Bflush(&obuf); 540 } 541 542 void 543 zname(char *n, int t, int s) 544 { 545 546 Bputc(&obuf, ANAME); 547 Bputc(&obuf, t); /* type */ 548 Bputc(&obuf, s); /* sym */ 549 while(*n) { 550 Bputc(&obuf, *n); 551 n++; 552 } 553 Bputc(&obuf, 0); 554 } 555 556 void 557 zaddr(Gen *a, int s) 558 { 559 long l; 560 int i; 561 char *n; 562 Ieee e; 563 564 Bputc(&obuf, a->type); 565 Bputc(&obuf, a->reg); 566 Bputc(&obuf, s); 567 Bputc(&obuf, a->name); 568 switch(a->type) { 569 default: 570 print("unknown type %d\n", a->type); 571 exits("arg"); 572 573 case D_NONE: 574 case D_REG: 575 case D_FREG: 576 case D_CREG: 577 case D_FPSCR: 578 case D_MSR: 579 case D_SREG: 580 case D_OPT: 581 break; 582 583 case D_SPR: 584 case D_OREG: 585 case D_CONST: 586 case D_BRANCH: 587 l = a->offset; 588 Bputc(&obuf, l); 589 Bputc(&obuf, l>>8); 590 Bputc(&obuf, l>>16); 591 Bputc(&obuf, l>>24); 592 break; 593 594 case D_SCONST: 595 n = a->sval; 596 for(i=0; i<NSNAME; i++) { 597 Bputc(&obuf, *n); 598 n++; 599 } 600 break; 601 602 case D_FCONST: 603 ieeedtod(&e, a->dval); 604 Bputc(&obuf, e.l); 605 Bputc(&obuf, e.l>>8); 606 Bputc(&obuf, e.l>>16); 607 Bputc(&obuf, e.l>>24); 608 Bputc(&obuf, e.h); 609 Bputc(&obuf, e.h>>8); 610 Bputc(&obuf, e.h>>16); 611 Bputc(&obuf, e.h>>24); 612 break; 613 } 614 } 615 616 int 617 outsim(Gen *g) 618 { 619 Sym *s; 620 int sno, t; 621 622 s = g->sym; 623 if(s == S) 624 return 0; 625 sno = s->sym; 626 if(sno < 0 || sno >= NSYM) 627 sno = 0; 628 t = g->name; 629 if(h[sno].type == t && h[sno].sym == s) 630 return sno; 631 zname(s->name, t, sym); 632 s->sym = sym; 633 h[sym].sym = s; 634 h[sym].type = t; 635 sno = sym; 636 sym++; 637 if(sym >= NSYM) 638 sym = 1; 639 return sno; 640 } 641 642 void 643 outcode(int a, Gen *g1, int reg, Gen *g2) 644 { 645 int sf, st; 646 647 if(a != AGLOBL && a != ADATA) 648 pc++; 649 if(pass == 1) 650 return; 651 if(g1->xreg != NREG) { 652 if(reg != NREG || g2->xreg != NREG) 653 yyerror("bad addressing modes"); 654 reg = g1->xreg; 655 } else 656 if(g2->xreg != NREG) { 657 if(reg != NREG) 658 yyerror("bad addressing modes"); 659 reg = g2->xreg; 660 } 661 do { 662 sf = outsim(g1); 663 st = outsim(g2); 664 } while(sf != 0 && st == sf); 665 Bputc(&obuf, a); 666 Bputc(&obuf, reg|nosched); 667 Bputc(&obuf, lineno); 668 Bputc(&obuf, lineno>>8); 669 Bputc(&obuf, lineno>>16); 670 Bputc(&obuf, lineno>>24); 671 zaddr(g1, sf); 672 zaddr(g2, st); 673 } 674 675 void 676 outgcode(int a, Gen *g1, int reg, Gen *g2, Gen *g3) 677 { 678 int s1, s2, s3, flag; 679 680 if(a != AGLOBL && a != ADATA) 681 pc++; 682 if(pass == 1) 683 return; 684 do { 685 s1 = outsim(g1); 686 s2 = outsim(g2); 687 s3 = outsim(g3); 688 } while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3)); 689 flag = 0; 690 if(g2->type != D_NONE) 691 flag = 0x40; /* flags extra operand */ 692 Bputc(&obuf, a); 693 Bputc(&obuf, reg | nosched | flag); 694 Bputc(&obuf, lineno); 695 Bputc(&obuf, lineno>>8); 696 Bputc(&obuf, lineno>>16); 697 Bputc(&obuf, lineno>>24); 698 zaddr(g1, s1); 699 if(flag) 700 zaddr(g2, s2); 701 zaddr(g3, s3); 702 } 703 704 void 705 outhist(void) 706 { 707 Gen g; 708 Hist *h; 709 char *p, *q, *op; 710 int n; 711 712 g = nullgen; 713 for(h = hist; h != H; h = h->link) { 714 p = h->name; 715 op = 0; 716 if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { 717 op = p; 718 p = pathname; 719 } 720 while(p) { 721 q = strchr(p, '/'); 722 if(q) { 723 n = q-p; 724 if(n == 0) 725 n = 1; /* leading "/" */ 726 q++; 727 } else { 728 n = strlen(p); 729 q = 0; 730 } 731 if(n) { 732 Bputc(&obuf, ANAME); 733 Bputc(&obuf, D_FILE); /* type */ 734 Bputc(&obuf, 1); /* sym */ 735 Bputc(&obuf, '<'); 736 Bwrite(&obuf, p, n); 737 Bputc(&obuf, 0); 738 } 739 p = q; 740 if(p == 0 && op) { 741 p = op; 742 op = 0; 743 } 744 } 745 g.offset = h->offset; 746 747 Bputc(&obuf, AHISTORY); 748 Bputc(&obuf, 0); 749 Bputc(&obuf, h->line); 750 Bputc(&obuf, h->line>>8); 751 Bputc(&obuf, h->line>>16); 752 Bputc(&obuf, h->line>>24); 753 zaddr(&nullgen, 0); 754 zaddr(&g, 0); 755 } 756 } 757 758 #include "../cc/lexbody" 759 #include "../cc/macbody" 760 #include "../cc/compat" 761