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