xref: /plan9-contrib/sys/src/cmd/qa/lex.c (revision ec59a3ddbfceee0efe34584c2c9981a5e5ff1ec4)
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_SPR:
666 	case D_OREG:
667 	case D_CONST:
668 	case D_BRANCH:
669 		l = a->offset;
670 		Bputc(&obuf, l);
671 		Bputc(&obuf, l>>8);
672 		Bputc(&obuf, l>>16);
673 		Bputc(&obuf, l>>24);
674 		break;
675 
676 	case D_SCONST:
677 		n = a->sval;
678 		for(i=0; i<NSNAME; i++) {
679 			Bputc(&obuf, *n);
680 			n++;
681 		}
682 		break;
683 
684 	case D_FCONST:
685 		ieeedtod(&e, a->dval);
686 		Bputc(&obuf, e.l);
687 		Bputc(&obuf, e.l>>8);
688 		Bputc(&obuf, e.l>>16);
689 		Bputc(&obuf, e.l>>24);
690 		Bputc(&obuf, e.h);
691 		Bputc(&obuf, e.h>>8);
692 		Bputc(&obuf, e.h>>16);
693 		Bputc(&obuf, e.h>>24);
694 		break;
695 	}
696 }
697 
698 int
699 outsim(Gen *g)
700 {
701 	Sym *s;
702 	int sno, t;
703 
704 	s = g->sym;
705 	if(s == S)
706 		return 0;
707 	sno = s->sym;
708 	if(sno < 0 || sno >= NSYM)
709 		sno = 0;
710 	t = g->name;
711 	if(h[sno].type == t && h[sno].sym == s)
712 		return sno;
713 	zname(s->name, t, sym);
714 	s->sym = sym;
715 	h[sym].sym = s;
716 	h[sym].type = t;
717 	sno = sym;
718 	sym++;
719 	if(sym >= NSYM)
720 		sym = 1;
721 	return sno;
722 }
723 
724 void
725 outcode(int a, Gen *g1, int reg, Gen *g2)
726 {
727 	int sf, st;
728 
729 	if(a != AGLOBL && a != ADATA)
730 		pc++;
731 	if(pass == 1)
732 		return;
733 	if(g1->xreg != NREG) {
734 		if(reg != NREG || g2->xreg != NREG)
735 			yyerror("bad addressing modes");
736 		reg = g1->xreg;
737 	} else
738 	if(g2->xreg != NREG) {
739 		if(reg != NREG)
740 			yyerror("bad addressing modes");
741 		reg = g2->xreg;
742 	}
743 	do {
744 		sf = outsim(g1);
745 		st = outsim(g2);
746 	} while(sf != 0 && st == sf);
747 	Bputc(&obuf, a);
748 	Bputc(&obuf, reg|nosched);
749 	Bputc(&obuf, lineno);
750 	Bputc(&obuf, lineno>>8);
751 	Bputc(&obuf, lineno>>16);
752 	Bputc(&obuf, lineno>>24);
753 	zaddr(g1, sf);
754 	zaddr(g2, st);
755 }
756 
757 void
758 outgcode(int a, Gen *g1, int reg, Gen *g2, Gen *g3)
759 {
760 	int s1, s2, s3, flag;
761 
762 	if(a != AGLOBL && a != ADATA)
763 		pc++;
764 	if(pass == 1)
765 		return;
766 	do {
767 		s1 = outsim(g1);
768 		s2 = outsim(g2);
769 		s3 = outsim(g3);
770 	} while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3));
771 	flag = 0;
772 	if(g2->type != D_NONE)
773 		flag = 0x40;	/* flags extra operand */
774 	Bputc(&obuf, a);
775 	Bputc(&obuf, reg | nosched | flag);
776 	Bputc(&obuf, lineno);
777 	Bputc(&obuf, lineno>>8);
778 	Bputc(&obuf, lineno>>16);
779 	Bputc(&obuf, lineno>>24);
780 	zaddr(g1, s1);
781 	if(flag)
782 		zaddr(g2, s2);
783 	zaddr(g3, s3);
784 }
785 
786 void
787 outhist(void)
788 {
789 	Gen g;
790 	Hist *h;
791 	char *p, *q, *op, c;
792 	int n;
793 
794 	g = nullgen;
795 	c = pathchar();
796 	for(h = hist; h != H; h = h->link) {
797 		p = h->name;
798 		op = 0;
799 		/* on windows skip drive specifier in pathname */
800 		if(systemtype(Windows) && p && p[1] == ':'){
801 			p += 2;
802 			c = *p;
803 		}
804 		if(p && p[0] != c && h->offset == 0 && pathname){
805 			/* on windows skip drive specifier in pathname */
806 			if(systemtype(Windows) && pathname[1] == ':') {
807 				op = p;
808 				p = pathname+2;
809 				c = *p;
810 			} else if(pathname[0] == c){
811 				op = p;
812 				p = pathname;
813 			}
814 		}
815 		while(p) {
816 			q = strchr(p, c);
817 			if(q) {
818 				n = q-p;
819 				if(n == 0){
820 					n = 1;	/* leading "/" */
821 					*p = '/';	/* don't emit "\" on windows */
822 				}
823 				q++;
824 			} else {
825 				n = strlen(p);
826 				q = 0;
827 			}
828 			if(n) {
829 				Bputc(&obuf, ANAME);
830 				Bputc(&obuf, D_FILE);	/* type */
831 				Bputc(&obuf, 1);	/* sym */
832 				Bputc(&obuf, '<');
833 				Bwrite(&obuf, p, n);
834 				Bputc(&obuf, 0);
835 			}
836 			p = q;
837 			if(p == 0 && op) {
838 				p = op;
839 				op = 0;
840 			}
841 		}
842 		g.offset = h->offset;
843 
844 		Bputc(&obuf, AHISTORY);
845 		Bputc(&obuf, 0);
846 		Bputc(&obuf, h->line);
847 		Bputc(&obuf, h->line>>8);
848 		Bputc(&obuf, h->line>>16);
849 		Bputc(&obuf, h->line>>24);
850 		zaddr(&nullgen, 0);
851 		zaddr(&g, 0);
852 	}
853 }
854 
855 #include "../cc/lexbody"
856 #include "../cc/macbody"
857 #include "../cc/compat"
858