xref: /plan9-contrib/sys/src/cmd/ka/lex.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 #include <bio.h>
5 #include "../kc/k.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 = 'k';
16 	thestring = "sparc";
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 	nosched = 0;
125 	pinit(*argv);
126 	for(i=0; i<nDlist; i++)
127 		dodefine(Dlist[i]);
128 	yyparse();
129 	if(nerrors) {
130 		cclean();
131 		errorexit();
132 	}
133 
134 	pass = 2;
135 	nosched = 0;
136 	outhist();
137 	pinit(*argv);
138 	for(i=0; i<nDlist; i++)
139 		dodefine(Dlist[i]);
140 	yyparse();
141 	cclean();
142 	if(nerrors)
143 		errorexit();
144 	exits(0);
145 }
146 
147 struct
148 {
149 	char	*name;
150 	ushort	type;
151 	ushort	value;
152 } itab[] =
153 {
154 	"SP",		LSP,	D_AUTO,
155 	"SB",		LSB,	D_EXTERN,
156 	"FP",		LFP,	D_PARAM,
157 	"PC",		LPC,	D_BRANCH,
158 
159 	"FSR",		LFSR,	D_FSR,
160 	"CSR",		LFSR,	D_CSR,
161 
162 	"FQ",		LFPQ,	D_FPQ,
163 	"CQ",		LFPQ,	D_CPQ,
164 
165 	"Y",		LPSR,	D_Y,
166 	"PSR",		LPSR,	D_PSR,
167 	"WIM",		LPSR,	D_WIM,
168 	"TBR",		LPSR,	D_TBR,
169 
170 	"R",		LR,	0,
171 	"R0",		LREG,	0,
172 	"R1",		LREG,	1,
173 	"R2",		LREG,	2,
174 	"R3",		LREG,	3,
175 	"R4",		LREG,	4,
176 	"R5",		LREG,	5,
177 	"R6",		LREG,	6,
178 	"R7",		LREG,	7,
179 	"R8",		LREG,	8,
180 	"R9",		LREG,	9,
181 	"R10",		LREG,	10,
182 	"R11",		LREG,	11,
183 	"R12",		LREG,	12,
184 	"R13",		LREG,	13,
185 	"R14",		LREG,	14,
186 	"R15",		LREG,	15,
187 	"R16",		LREG,	16,
188 	"R17",		LREG,	17,
189 	"R18",		LREG,	18,
190 	"R19",		LREG,	19,
191 	"R20",		LREG,	20,
192 	"R21",		LREG,	21,
193 	"R22",		LREG,	22,
194 	"R23",		LREG,	23,
195 	"R24",		LREG,	24,
196 	"R25",		LREG,	25,
197 	"R26",		LREG,	26,
198 	"R27",		LREG,	27,
199 	"R28",		LREG,	28,
200 	"R29",		LREG,	29,
201 	"R30",		LREG,	30,
202 	"R31",		LREG,	31,
203 
204 	"C",		LC,	0,
205 	"C0",		LCREG,	0,
206 	"C1",		LCREG,	1,
207 	"C2",		LCREG,	2,
208 	"C3",		LCREG,	3,
209 	"C4",		LCREG,	4,
210 	"C5",		LCREG,	5,
211 	"C6",		LCREG,	6,
212 	"C7",		LCREG,	7,
213 	"C8",		LCREG,	8,
214 	"C9",		LCREG,	9,
215 	"C10",		LCREG,	10,
216 	"C11",		LCREG,	11,
217 	"C12",		LCREG,	12,
218 	"C13",		LCREG,	13,
219 	"C14",		LCREG,	14,
220 	"C15",		LCREG,	15,
221 	"C16",		LCREG,	16,
222 	"C17",		LCREG,	17,
223 	"C18",		LCREG,	18,
224 	"C19",		LCREG,	19,
225 	"C20",		LCREG,	20,
226 	"C21",		LCREG,	21,
227 	"C22",		LCREG,	22,
228 	"C23",		LCREG,	23,
229 	"C24",		LCREG,	24,
230 	"C25",		LCREG,	25,
231 	"C26",		LCREG,	26,
232 	"C27",		LCREG,	27,
233 	"C28",		LCREG,	28,
234 	"C29",		LCREG,	29,
235 	"C30",		LCREG,	30,
236 	"C31",		LCREG,	31,
237 
238 	"F",		LF,	0,
239 	"F0",		LFREG,	0,
240 	"F2",		LFREG,	2,
241 	"F4",		LFREG,	4,
242 	"F6",		LFREG,	6,
243 	"F8",		LFREG,	8,
244 	"F10",		LFREG,	10,
245 	"F12",		LFREG,	12,
246 	"F14",		LFREG,	14,
247 	"F16",		LFREG,	16,
248 	"F18",		LFREG,	18,
249 	"F20",		LFREG,	20,
250 	"F22",		LFREG,	22,
251 	"F24",		LFREG,	24,
252 	"F26",		LFREG,	26,
253 	"F28",		LFREG,	28,
254 	"F30",		LFREG,	30,
255 	"F1",		LFREG,	1,
256 	"F3",		LFREG,	3,
257 	"F5",		LFREG,	5,
258 	"F7",		LFREG,	7,
259 	"F9",		LFREG,	9,
260 	"F11",		LFREG,	11,
261 	"F13",		LFREG,	13,
262 	"F15",		LFREG,	15,
263 	"F17",		LFREG,	17,
264 	"F19",		LFREG,	19,
265 	"F21",		LFREG,	21,
266 	"F23",		LFREG,	23,
267 	"F25",		LFREG,	25,
268 	"F27",		LFREG,	27,
269 	"F29",		LFREG,	29,
270 	"F31",		LFREG,	31,
271 
272 	"ADD",		LADDW, AADD,
273 	"ADDCC",	LADDW, AADDCC,
274 	"ADDX",		LADDW, AADDX,
275 	"ADDXCC",	LADDW, AADDXCC,
276 	"AND",		LADDW, AAND,
277 	"ANDCC",	LADDW, AANDCC,
278 	"ANDN",		LADDW, AANDN,
279 	"ANDNCC",	LADDW, AANDNCC,
280 	"BA",		LBRA, ABA,
281 	"BCC",		LBRA, ABCC,
282 	"BCS",		LBRA, ABCS,
283 	"BE",		LBRA, ABE,
284 	"BG",		LBRA, ABG,
285 	"BGE",		LBRA, ABGE,
286 	"BGU",		LBRA, ABGU,
287 	"BL",		LBRA, ABL,
288 	"BLE",		LBRA, ABLE,
289 	"BLEU",		LBRA, ABLEU,
290 	"BN",		LBRA, ABN,
291 	"BNE",		LBRA, ABNE,
292 	"BNEG",		LBRA, ABNEG,
293 	"BPOS",		LBRA, ABPOS,
294 	"BVC",		LBRA, ABVC,
295 	"BVS",		LBRA, ABVS,
296 	"CB0",		LBRA, ACB0,
297 	"CB01",		LBRA, ACB01,
298 	"CB012",	LBRA, ACB012,
299 	"CB013",	LBRA, ACB013,
300 	"CB02",		LBRA, ACB02,
301 	"CB023",	LBRA, ACB023,
302 	"CB03",		LBRA, ACB03,
303 	"CB1",		LBRA, ACB1,
304 	"CB12",		LBRA, ACB12,
305 	"CB123",	LBRA, ACB123,
306 	"CB13",		LBRA, ACB13,
307 	"CB2",		LBRA, ACB2,
308 	"CB23",		LBRA, ACB23,
309 	"CB3",		LBRA, ACB3,
310 	"CBA",		LBRA, ACBA,
311 	"CBN",		LBRA, ACBN,
312 	"CMP",		LCMP, ACMP,
313 	"CPOP1",	LCPOP, ACPOP1,
314 	"CPOP2",	LCPOP, ACPOP2,
315 	"DATA",		LDATA, ADATA,
316 	"DIV",		LADDW, ADIV,
317 	"DIVL",		LADDW, ADIVL,
318 	"END",		LEND, AEND,
319 	"FABSD",	LFCONV, AFABSD,
320 	"FABSF",	LFCONV, AFABSF,
321 	"FABSX",	LFCONV, AFABSX,
322 	"FADDD",	LFADD, AFADDD,
323 	"FADDF",	LFADD, AFADDF,
324 	"FADDX",	LFADD, AFADDX,
325 	"FBA",		LBRA, AFBA,
326 	"FBE",		LBRA, AFBE,
327 	"FBG",		LBRA, AFBG,
328 	"FBGE",		LBRA, AFBGE,
329 	"FBL",		LBRA, AFBL,
330 	"FBLE",		LBRA, AFBLE,
331 	"FBLG",		LBRA, AFBLG,
332 	"FBN",		LBRA, AFBN,
333 	"FBNE",		LBRA, AFBNE,
334 	"FBO",		LBRA, AFBO,
335 	"FBU",		LBRA, AFBU,
336 	"FBUE",		LBRA, AFBUE,
337 	"FBUG",		LBRA, AFBUG,
338 	"FBUGE",	LBRA, AFBUGE,
339 	"FBUL",		LBRA, AFBUL,
340 	"FBULE",	LBRA, AFBULE,
341 	"FCMPD",	LFADD, AFCMPD,
342 	"FCMPED",	LFADD, AFCMPED,
343 	"FCMPEF",	LFADD, AFCMPEF,
344 	"FCMPEX",	LFADD, AFCMPEX,
345 	"FCMPF",	LFADD, AFCMPF,
346 	"FCMPX",	LFADD, AFCMPX,
347 	"FDIVD",	LFADD, AFDIVD,
348 	"FDIVF",	LFADD, AFDIVF,
349 	"FDIVX",	LFADD, AFDIVX,
350 	"FMOVD",	LFMOV, AFMOVD,
351 	"FMOVDF",	LFCONV, AFMOVDF,
352 	"FMOVDW",	LFCONV, AFMOVDW,
353 	"FMOVDX",	LFCONV, AFMOVDX,
354 	"FMOVF",	LFMOV, AFMOVF,
355 	"FMOVFD",	LFCONV, AFMOVFD,
356 	"FMOVFW",	LFCONV, AFMOVFW,
357 	"FMOVFX",	LFCONV, AFMOVFX,
358 	"FMOVWD",	LFCONV, AFMOVWD,
359 	"FMOVWF",	LFCONV, AFMOVWF,
360 	"FMOVWX",	LFCONV, AFMOVWX,
361 	"FMOVX",	LFCONV, AFMOVX,
362 	"FMOVXD",	LFCONV, AFMOVXD,
363 	"FMOVXF",	LFCONV, AFMOVXF,
364 	"FMOVXW",	LFCONV, AFMOVXW,
365 	"FMULD",	LFADD, AFMULD,
366 	"FMULF",	LFADD, AFMULF,
367 	"FMULX",	LFADD, AFMULX,
368 	"FNEGD",	LFCONV, AFNEGD,
369 	"FNEGF",	LFCONV, AFNEGF,
370 	"FNEGX",	LFCONV, AFNEGX,
371 	"FSQRTD",	LFCONV, AFSQRTD,
372 	"FSQRTF",	LFCONV, AFSQRTF,
373 	"FSQRTX",	LFCONV, AFSQRTX,
374 	"FSUBD",	LFADD, AFSUBD,
375 	"FSUBF",	LFADD, AFSUBF,
376 	"FSUBX",	LFADD, AFSUBX,
377 	"GLOBL",	LTEXT, AGLOBL,
378 	"IFLUSH",	LFLUSH, AIFLUSH,
379 	"JMPL",		LJMPL, AJMPL,
380 	"JMP",		LJMPL, AJMP,
381 	"MOD",		LADDW, AMOD,
382 	"MODL",		LADDW, AMODL,
383 	"MOVB",		LMOVB, AMOVB,
384 	"MOVBU",	LMOVB, AMOVBU,
385 	"MOVD",		LMOVD, AMOVD,
386 	"MOVH",		LMOVB, AMOVH,
387 	"MOVHU",	LMOVB, AMOVHU,
388 	"MOVW",		LMOVW, AMOVW,
389 	"MUL",		LADDW, AMUL,
390 	"MULSCC",	LADDW, AMULSCC,
391 	"NOP",		LNOP, ANOP,
392 	"OR",		LADDW, AOR,
393 	"ORCC",		LADDW, AORCC,
394 	"ORN",		LADDW, AORN,
395 	"ORNCC",	LADDW, AORNCC,
396 	"RESTORE",	LADDW, ARESTORE,
397 	"RETT",		LRETT, ARETT,
398 	"RETURN",	LRETRN, ARETURN,
399 	"SAVE",		LADDW, ASAVE,
400 	"SLL",		LADDW, ASLL,
401 	"SRA",		LADDW, ASRA,
402 	"SRL",		LADDW, ASRL,
403 	"SUB",		LADDW, ASUB,
404 	"SUBCC",	LADDW, ASUBCC,
405 	"SUBX",		LADDW, ASUBX,
406 	"SUBXCC",	LADDW, ASUBXCC,
407 	"SWAP",		LSWAP, ASWAP,
408 	"TA",		LTRAP, ATA,
409 	"TADDCC",	LADDW, ATADDCC,
410 	"TADDCCTV",	LADDW, ATADDCCTV,
411 	"TAS",		LSWAP, ATAS,
412 	"TCC",		LTRAP, ATCC,
413 	"TCS",		LTRAP, ATCS,
414 	"TE",		LTRAP, ATE,
415 	"TEXT",		LTEXT, ATEXT,
416 	"TG",		LTRAP, ATG,
417 	"TGE",		LTRAP, ATGE,
418 	"TGU",		LTRAP, ATGU,
419 	"TL",		LTRAP, ATL,
420 	"TLE",		LTRAP, ATLE,
421 	"TLEU",		LTRAP, ATLEU,
422 	"TN",		LTRAP, ATN,
423 	"TNE",		LTRAP, ATNE,
424 	"TNEG",		LTRAP, ATNEG,
425 	"TPOS",		LTRAP, ATPOS,
426 	"TSUBCC",	LADDW, ATSUBCC,
427 	"TSUBCCTV",	LADDW, ATSUBCCTV,
428 	"TVC",		LTRAP, ATVC,
429 	"TVS",		LTRAP, ATVS,
430 	"UNIMP",	LUNIMP, AUNIMP,
431 	"WORD",		LUNIMP, AWORD,
432 	"XNOR",		LADDW, AXNOR,
433 	"XNORCC",	LADDW, AXNORCC,
434 	"XOR",		LXORW, AXOR,
435 	"XORCC",	LADDW, AXORCC,
436 
437 	"SCHED",	LSCHED, 0,
438 	"NOSCHED",	LSCHED, 0x80,
439 
440 	0
441 };
442 
443 void
444 cinit(void)
445 {
446 	Sym *s;
447 	int i;
448 
449 	nullgen.sym = S;
450 	nullgen.offset = 0;
451 	nullgen.type = D_NONE;
452 	nullgen.name = D_NONE;
453 	nullgen.reg = NREG;
454 	nullgen.xreg = NREG;
455 	if(FPCHIP)
456 		nullgen.dval = 0;
457 	for(i=0; i<sizeof(nullgen.sval); i++)
458 		nullgen.sval[i] = 0;
459 
460 	nerrors = 0;
461 	iostack = I;
462 	iofree = I;
463 	peekc = IGN;
464 	nhunk = 0;
465 	for(i=0; i<NHASH; i++)
466 		hash[i] = S;
467 	for(i=0; itab[i].name; i++) {
468 		s = slookup(itab[i].name);
469 		s->type = itab[i].type;
470 		s->value = itab[i].value;
471 	}
472 
473 	ALLOCN(pathname, 0, 100);
474 	if(getwd(pathname, 99) == 0) {
475 		ALLOCN(pathname, 100, 900);
476 		if(getwd(pathname, 999) == 0)
477 			strcpy(pathname, "/???");
478 	}
479 }
480 
481 void
482 syminit(Sym *s)
483 {
484 
485 	s->type = LNAME;
486 	s->value = 0;
487 }
488 
489 void
490 cclean(void)
491 {
492 
493 	outcode(AEND, &nullgen, NREG, &nullgen);
494 	Bflush(&obuf);
495 }
496 
497 void
498 zname(char *n, int t, int s)
499 {
500 
501 	Bputc(&obuf, ANAME);
502 	Bputc(&obuf, t);	/* type */
503 	Bputc(&obuf, s);	/* sym */
504 	while(*n) {
505 		Bputc(&obuf, *n);
506 		n++;
507 	}
508 	Bputc(&obuf, 0);
509 }
510 
511 void
512 zaddr(Gen *a, int s)
513 {
514 	long l;
515 	int i;
516 	char *n;
517 	Ieee e;
518 
519 	Bputc(&obuf, a->type);
520 	Bputc(&obuf, a->reg);
521 	Bputc(&obuf, s);
522 	Bputc(&obuf, a->name);
523 	switch(a->type) {
524 	default:
525 		print("unknown type %d\n", a->type);
526 		exits("arg");
527 
528 	case D_NONE:
529 	case D_REG:
530 	case D_FREG:
531 	case D_CREG:
532 	case D_PREG:
533 		break;
534 
535 	case D_OREG:
536 	case D_ASI:
537 	case D_CONST:
538 	case D_BRANCH:
539 		l = a->offset;
540 		Bputc(&obuf, l);
541 		Bputc(&obuf, l>>8);
542 		Bputc(&obuf, l>>16);
543 		Bputc(&obuf, l>>24);
544 		break;
545 
546 	case D_SCONST:
547 		n = a->sval;
548 		for(i=0; i<NSNAME; i++) {
549 			Bputc(&obuf, *n);
550 			n++;
551 		}
552 		break;
553 
554 	case D_FCONST:
555 		ieeedtod(&e, a->dval);
556 		Bputc(&obuf, e.l);
557 		Bputc(&obuf, e.l>>8);
558 		Bputc(&obuf, e.l>>16);
559 		Bputc(&obuf, e.l>>24);
560 		Bputc(&obuf, e.h);
561 		Bputc(&obuf, e.h>>8);
562 		Bputc(&obuf, e.h>>16);
563 		Bputc(&obuf, e.h>>24);
564 		break;
565 	}
566 }
567 
568 void
569 outcode(int a, Gen *g1, int reg, Gen *g2)
570 {
571 	int sf, st, t;
572 	Sym *s;
573 
574 	if(pass == 1)
575 		goto out;
576 	if(g1->xreg != NREG) {
577 		if(reg != NREG || g2->xreg != NREG)
578 			yyerror("bad addressing modes");
579 		reg = g1->xreg;
580 	} else
581 	if(g2->xreg != NREG) {
582 		if(reg != NREG)
583 			yyerror("bad addressing modes");
584 		reg = g2->xreg;
585 	}
586 jackpot:
587 	sf = 0;
588 	s = g1->sym;
589 	while(s != S) {
590 		sf = s->sym;
591 		if(sf < 0 || sf >= NSYM)
592 			sf = 0;
593 		t = g1->name;
594 		if(h[sf].type == t)
595 		if(h[sf].sym == s)
596 			break;
597 		zname(s->name, t, sym);
598 		s->sym = sym;
599 		h[sym].sym = s;
600 		h[sym].type = t;
601 		sf = sym;
602 		sym++;
603 		if(sym >= NSYM)
604 			sym = 1;
605 		break;
606 	}
607 	st = 0;
608 	s = g2->sym;
609 	while(s != S) {
610 		st = s->sym;
611 		if(st < 0 || st >= NSYM)
612 			st = 0;
613 		t = g2->name;
614 		if(h[st].type == t)
615 		if(h[st].sym == s)
616 			break;
617 		zname(s->name, t, sym);
618 		s->sym = sym;
619 		h[sym].sym = s;
620 		h[sym].type = t;
621 		st = sym;
622 		sym++;
623 		if(sym >= NSYM)
624 			sym = 1;
625 		if(st == sf)
626 			goto jackpot;
627 		break;
628 	}
629 	Bputc(&obuf, a);
630 	Bputc(&obuf, reg|nosched);
631 	Bputc(&obuf, lineno);
632 	Bputc(&obuf, lineno>>8);
633 	Bputc(&obuf, lineno>>16);
634 	Bputc(&obuf, lineno>>24);
635 	zaddr(g1, sf);
636 	zaddr(g2, st);
637 
638 out:
639 	if(a != AGLOBL && a != ADATA)
640 		pc++;
641 }
642 
643 void
644 outhist(void)
645 {
646 	Gen g;
647 	Hist *h;
648 	char *p, *q, *op;
649 	int n;
650 
651 	g = nullgen;
652 	for(h = hist; h != H; h = h->link) {
653 		p = h->name;
654 		op = 0;
655 		if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') {
656 			op = p;
657 			p = pathname;
658 		}
659 		while(p) {
660 			q = strchr(p, '/');
661 			if(q) {
662 				n = q-p;
663 				if(n == 0)
664 					n = 1;	/* leading "/" */
665 				q++;
666 			} else {
667 				n = strlen(p);
668 				q = 0;
669 			}
670 			if(n) {
671 				Bputc(&obuf, ANAME);
672 				Bputc(&obuf, D_FILE);	/* type */
673 				Bputc(&obuf, 1);	/* sym */
674 				Bputc(&obuf, '<');
675 				Bwrite(&obuf, p, n);
676 				Bputc(&obuf, 0);
677 			}
678 			p = q;
679 			if(p == 0 && op) {
680 				p = op;
681 				op = 0;
682 			}
683 		}
684 		g.offset = h->offset;
685 
686 		Bputc(&obuf, AHISTORY);
687 		Bputc(&obuf, 0);
688 		Bputc(&obuf, h->line);
689 		Bputc(&obuf, h->line>>8);
690 		Bputc(&obuf, h->line>>16);
691 		Bputc(&obuf, h->line>>24);
692 		zaddr(&nullgen, 0);
693 		zaddr(&g, 0);
694 	}
695 }
696 
697 #include "../cc/lexbody"
698 #include "../cc/macbody"
699