xref: /plan9-contrib/sys/src/cmd/9a/lex.c (revision fbadb1c4d4463e58337ffb1ed396c9caee5d1889)
1 #define	EXTERN
2 #include "a.h"
3 #include "y.tab.h"
4 #include <ctype.h>
5 
6 void
main(int argc,char * argv[])7 main(int argc, char *argv[])
8 {
9 	char *p;
10 	int nout, nproc, status, i, c;
11 
12 	thechar = '9';
13 	thestring = "power64";
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
assemble(char * file)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 	"CR",		LCR,	0,
175 	"CR0",		LCREG,	0,
176 	"CR1",		LCREG,	1,
177 	"CR2",		LCREG,	2,
178 	"CR3",		LCREG,	3,
179 	"CR4",		LCREG,	4,
180 	"CR5",		LCREG,	5,
181 	"CR6",		LCREG,	6,
182 	"CR7",		LCREG,	7,
183 
184 	"R",		LR,	0,
185 	"R0",		LREG,	0,
186 	"R1",		LREG,	1,
187 	"R2",		LREG,	2,
188 	"R3",		LREG,	3,
189 	"R4",		LREG,	4,
190 	"R5",		LREG,	5,
191 	"R6",		LREG,	6,
192 	"R7",		LREG,	7,
193 	"R8",		LREG,	8,
194 	"R9",		LREG,	9,
195 	"R10",		LREG,	10,
196 	"R11",		LREG,	11,
197 	"R12",		LREG,	12,
198 	"R13",		LREG,	13,
199 	"R14",		LREG,	14,
200 	"R15",		LREG,	15,
201 	"R16",		LREG,	16,
202 	"R17",		LREG,	17,
203 	"R18",		LREG,	18,
204 	"R19",		LREG,	19,
205 	"R20",		LREG,	20,
206 	"R21",		LREG,	21,
207 	"R22",		LREG,	22,
208 	"R23",		LREG,	23,
209 	"R24",		LREG,	24,
210 	"R25",		LREG,	25,
211 	"R26",		LREG,	26,
212 	"R27",		LREG,	27,
213 	"R28",		LREG,	28,
214 	"R29",		LREG,	29,
215 	"R30",		LREG,	30,
216 	"R31",		LREG,	31,
217 
218 	"F",		LF,	0,
219 	"F0",		LFREG,	0,
220 	"F1",		LFREG,	1,
221 	"F2",		LFREG,	2,
222 	"F3",		LFREG,	3,
223 	"F4",		LFREG,	4,
224 	"F5",		LFREG,	5,
225 	"F6",		LFREG,	6,
226 	"F7",		LFREG,	7,
227 	"F8",		LFREG,	8,
228 	"F9",		LFREG,	9,
229 	"F10",		LFREG,	10,
230 	"F11",		LFREG,	11,
231 	"F12",		LFREG,	12,
232 	"F13",		LFREG,	13,
233 	"F14",		LFREG,	14,
234 	"F15",		LFREG,	15,
235 	"F16",		LFREG,	16,
236 	"F17",		LFREG,	17,
237 	"F18",		LFREG,	18,
238 	"F19",		LFREG,	19,
239 	"F20",		LFREG,	20,
240 	"F21",		LFREG,	21,
241 	"F22",		LFREG,	22,
242 	"F23",		LFREG,	23,
243 	"F24",		LFREG,	24,
244 	"F25",		LFREG,	25,
245 	"F26",		LFREG,	26,
246 	"F27",		LFREG,	27,
247 	"F28",		LFREG,	28,
248 	"F29",		LFREG,	29,
249 	"F30",		LFREG,	30,
250 	"F31",		LFREG,	31,
251 
252 	"CREQV",	LCROP, ACREQV,
253 	"CRXOR",	LCROP, ACRXOR,
254 	"CRAND",	LCROP, ACRAND,
255 	"CROR",		LCROP, ACROR,
256 	"CRANDN",	LCROP, ACRANDN,
257 	"CRORN",	LCROP, ACRORN,
258 	"CRNAND",	LCROP, ACRNAND,
259 	"CRNOR",	LCROP, ACRNOR,
260 
261 	"ADD",		LADDW, AADD,
262 	"ADDV",		LADDW, AADDV,
263 	"ADDCC",	LADDW, AADDCC,
264 	"ADDVCC",	LADDW, AADDVCC,
265 	"ADDC",		LADDW, AADDC,
266 	"ADDCV",	LADDW, AADDCV,
267 	"ADDCCC",	LADDW, AADDCCC,
268 	"ADDCVCC",	LADDW, AADDCVCC,
269 	"ADDE",		LLOGW, AADDE,
270 	"ADDEV",	LLOGW, AADDEV,
271 	"ADDECC",	LLOGW, AADDECC,
272 	"ADDEVCC",	LLOGW, AADDEVCC,
273 
274 	"ADDME",	LABS, AADDME,
275 	"ADDMEV",	LABS, AADDMEV,
276 	"ADDMECC",	LABS, AADDMECC,
277 	"ADDMEVCC",	LABS, AADDMEVCC,
278 	"ADDZE",	LABS, AADDZE,
279 	"ADDZEV",	LABS, AADDZEV,
280 	"ADDZECC",	LABS, AADDZECC,
281 	"ADDZEVCC",	LABS, AADDZEVCC,
282 
283 	"SUB",		LADDW, ASUB,
284 	"SUBV",		LADDW, ASUBV,
285 	"SUBCC",	LADDW, ASUBCC,
286 	"SUBVCC",	LADDW, ASUBVCC,
287 	"SUBE",		LLOGW, ASUBE,
288 	"SUBECC",	LLOGW, ASUBECC,
289 	"SUBEV",	LLOGW, ASUBEV,
290 	"SUBEVCC",	LLOGW, ASUBEVCC,
291 	"SUBC",		LADDW, ASUBC,
292 	"SUBCCC",	LADDW, ASUBCCC,
293 	"SUBCV",	LADDW, ASUBCV,
294 	"SUBCVCC",	LADDW, ASUBCVCC,
295 
296 	"SUBME",	LABS, ASUBME,
297 	"SUBMEV",	LABS, ASUBMEV,
298 	"SUBMECC",	LABS, ASUBMECC,
299 	"SUBMEVCC",	LABS, ASUBMEVCC,
300 	"SUBZE",	LABS, ASUBZE,
301 	"SUBZEV",	LABS, ASUBZEV,
302 	"SUBZECC",	LABS, ASUBZECC,
303 	"SUBZEVCC",	LABS, ASUBZEVCC,
304 
305 	"AND",		LADDW, AAND,
306 	"ANDCC",	LADDW, AANDCC,	/* includes andil & andiu */
307 	"ANDN",		LLOGW, AANDN,
308 	"ANDNCC",	LLOGW, AANDNCC,
309 	"EQV",		LLOGW, AEQV,
310 	"EQVCC",	LLOGW, AEQVCC,
311 	"NAND",		LLOGW, ANAND,
312 	"NANDCC",	LLOGW, ANANDCC,
313 	"NOR",		LLOGW, ANOR,
314 	"NORCC",	LLOGW, ANORCC,
315 	"OR",		LADDW, AOR,	/* includes oril & oriu */
316 	"ORCC",		LADDW, AORCC,
317 	"ORN",		LLOGW, AORN,
318 	"ORNCC",	LLOGW, AORNCC,
319 	"XOR",		LADDW, AXOR,	/* includes xoril & xoriu */
320 	"XORCC",	LLOGW, AXORCC,
321 
322 	"EXTSB",	LABS,	AEXTSB,
323 	"EXTSBCC",	LABS,	AEXTSBCC,
324 	"EXTSH",	LABS, AEXTSH,
325 	"EXTSHCC",	LABS, AEXTSHCC,
326 
327 	"CNTLZW",	LABS, ACNTLZW,
328 	"CNTLZWCC",	LABS, ACNTLZWCC,
329 
330 	"RLWMI",	LRLWM, ARLWMI,
331 	"RLWMICC",	LRLWM, ARLWMICC,
332 	"RLWNM",	LRLWM, ARLWNM,
333 	"RLWNMCC", LRLWM, ARLWNMCC,
334 
335 	"SLW",		LSHW, ASLW,
336 	"SLWCC",	LSHW, ASLWCC,
337 	"SRW",		LSHW, ASRW,
338 	"SRWCC",	LSHW, ASRWCC,
339 	"SRAW",		LSHW, ASRAW,
340 	"SRAWCC",	LSHW, ASRAWCC,
341 
342 	"BR",		LBRA, ABR,
343 	"BC",		LBRA, ABC,
344 	"BCL",		LBRA, ABC,
345 	"BL",		LBRA, ABL,
346 	"BEQ",		LBRA, ABEQ,
347 	"BNE",		LBRA, ABNE,
348 	"BGT",		LBRA, ABGT,
349 	"BGE",		LBRA, ABGE,
350 	"BLT",		LBRA, ABLT,
351 	"BLE",		LBRA, ABLE,
352 	"BVC",		LBRA, ABVC,
353 	"BVS",		LBRA, ABVS,
354 
355 	"CMP",		LCMP, ACMP,
356 	"CMPU",		LCMP, ACMPU,
357 
358 	"DIVW",		LLOGW, ADIVW,
359 	"DIVWV",	LLOGW, ADIVWV,
360 	"DIVWCC",	LLOGW, ADIVWCC,
361 	"DIVWVCC",	LLOGW, ADIVWVCC,
362 	"DIVWU",	LLOGW, ADIVWU,
363 	"DIVWUV",	LLOGW, ADIVWUV,
364 	"DIVWUCC",	LLOGW, ADIVWUCC,
365 	"DIVWUVCC",	LLOGW, ADIVWUVCC,
366 
367 	"FABS",		LFCONV,	AFABS,
368 	"FABSCC",	LFCONV,	AFABSCC,
369 	"FNEG",		LFCONV,	AFNEG,
370 	"FNEGCC",	LFCONV,	AFNEGCC,
371 	"FNABS",	LFCONV,	AFNABS,
372 	"FNABSCC",	LFCONV,	AFNABSCC,
373 
374 	"FADD",		LFADD,	AFADD,
375 	"FADDCC",	LFADD,	AFADDCC,
376 	"FSUB",		LFADD,  AFSUB,
377 	"FSUBCC",	LFADD,	AFSUBCC,
378 	"FMUL",		LFADD,	AFMUL,
379 	"FMULCC",	LFADD,	AFMULCC,
380 	"FDIV",		LFADD,	AFDIV,
381 	"FDIVCC",	LFADD,	AFDIVCC,
382 	"FRSP",		LFCONV,	AFRSP,
383 	"FRSPCC",	LFCONV,	AFRSPCC,
384 	"FCTIW",	LFCONV,	AFCTIW,
385 	"FCTIWCC",	LFCONV,	AFCTIWCC,
386 	"FCTIWZ",	LFCONV,	AFCTIWZ,
387 	"FCTIWZCC",	LFCONV,	AFCTIWZCC,
388 
389 	"FMADD",	LFMA, AFMADD,
390 	"FMADDCC",	LFMA, AFMADDCC,
391 	"FMSUB",	LFMA, AFMSUB,
392 	"FMSUBCC",	LFMA, AFMSUBCC,
393 	"FNMADD",	LFMA, AFNMADD,
394 	"FNMADDCC",	LFMA, AFNMADDCC,
395 	"FNMSUB",	LFMA, AFNMSUB,
396 	"FNMSUBCC",	LFMA, AFNMSUBCC,
397 	"FMADDS",	LFMA, AFMADDS,
398 	"FMADDSCC",	LFMA, AFMADDSCC,
399 	"FMSUBS",	LFMA, AFMSUBS,
400 	"FMSUBSCC",	LFMA, AFMSUBSCC,
401 	"FNMADDS",	LFMA, AFNMADDS,
402 	"FNMADDSCC",	LFMA, AFNMADDSCC,
403 	"FNMSUBS",	LFMA, AFNMSUBS,
404 	"FNMSUBSCC",	LFMA, AFNMSUBSCC,
405 
406 	"FCMPU",	LFCMP, AFCMPU,
407 	"FCMPO",	LFCMP, AFCMPO,
408 	"MTFSB0",	LMTFSB, AMTFSB0,
409 	"MTFSB1",	LMTFSB,	AMTFSB1,
410 
411 	"FMOVD",	LFMOV, AFMOVD,
412 	"FMOVS",	LFMOV, AFMOVS,
413 	"FMOVDCC",	LFCONV,	AFMOVDCC,	/* fmr. */
414 
415 	"GLOBL",	LTEXT, AGLOBL,
416 
417 	"MOVB",		LMOVB, AMOVB,
418 	"MOVBZ",	LMOVB, AMOVBZ,
419 	"MOVBU",	LMOVB, AMOVBU,
420 	"MOVBZU", LMOVB, AMOVBZU,
421 	"MOVH",		LMOVB, AMOVH,
422 	"MOVHZ",	LMOVB, AMOVHZ,
423 	"MOVHU",	LMOVB, AMOVHU,
424 	"MOVHZU", LMOVB, AMOVHZU,
425 	"MOVHBR", 	LXMV, AMOVHBR,
426 	"MOVWBR",	LXMV, AMOVWBR,
427 	"MOVW",		LMOVW, AMOVW,
428 	"MOVWU",	LMOVW, AMOVWU,
429 	"MOVMW",	LMOVMW, AMOVMW,
430 	"MOVFL",	LMOVW,	AMOVFL,
431 
432 	"MULLW",	LADDW, AMULLW,		/* includes multiply immediate 10-139 */
433 	"MULLWV",	LLOGW, AMULLWV,
434 	"MULLWCC",	LLOGW, AMULLWCC,
435 	"MULLWVCC",	LLOGW, AMULLWVCC,
436 
437 	"MULHW",	LLOGW, AMULHW,
438 	"MULHWCC",	LLOGW, AMULHWCC,
439 	"MULHWU",	LLOGW, AMULHWU,
440 	"MULHWUCC",	LLOGW, AMULHWUCC,
441 
442 	"NEG",		LABS, ANEG,
443 	"NEGV",		LABS, ANEGV,
444 	"NEGCC",	LABS, ANEGCC,
445 	"NEGVCC",	LABS, ANEGVCC,
446 
447 	"NOP",		LNOP, ANOP,	/* ori 0,0,0 */
448 	"SYSCALL",	LNOP, ASYSCALL,
449 
450 	"RETURN",	LRETRN, ARETURN,
451 	"RFI",		LRETRN,	ARFI,
452 	"RFCI",		LRETRN,	ARFCI,
453 
454 	"DATA",		LDATA, ADATA,
455 	"END",		LEND, AEND,
456 	"TEXT",		LTEXT, ATEXT,
457 
458 	/* 64-bit instructions */
459 	"CNTLZD",	LABS,	ACNTLZD,
460 	"CNTLZDCC",	LABS,	ACNTLZDCC,
461 	"DIVD",	LLOGW,	ADIVD,
462 	"DIVDCC",	LLOGW,	ADIVDCC,
463 	"DIVDVCC",	LLOGW,	ADIVDVCC,
464 	"DIVDV",	LLOGW,	ADIVDV,
465 	"DIVDU",	LLOGW,	ADIVDU,
466 	"DIVDUCC",	LLOGW,	ADIVDUCC,
467 	"DIVDUVCC",	LLOGW,	ADIVDUVCC,
468 	"DIVDUV",	LLOGW,	ADIVDUV,
469 	"EXTSW",	LABS, AEXTSW,
470 	"EXTSWCC",	LABS, AEXTSWCC,
471 	"FCTID",	LFCONV,	AFCTID,
472 	"FCTIDCC",	LFCONV,	AFCTIDCC,
473 	"FCTIDZ",	LFCONV,	AFCTIDZ,
474 	"FCTIDZCC",	LFCONV,	AFCTIDZCC,
475 	"FCFID",	LFCONV,	AFCFID,
476 	"FCFIDCC",	LFCONV,	AFCFIDCC,
477 	"LDAR", LXLD, ALDAR,
478 	"MOVD",	LMOVW,	AMOVD,
479 	"MOVDU",	LMOVW,	AMOVDU,
480 	"MOVWZ",	LMOVW,	AMOVWZ,
481 	"MOVWZU",	LMOVW,	AMOVWZU,
482 	"MULHD",	LLOGW,	AMULHD,
483 	"MULHDCC",	LLOGW,	AMULHDCC,
484 	"MULHDU",	LLOGW,	AMULHDU,
485 	"MULHDUCC",	LLOGW,	AMULHDUCC,
486 	"MULLD",	LADDW,	AMULLD,	/* includes multiply immediate? */
487 	"MULLDCC",	LLOGW,	AMULLDCC,
488 	"MULLDVCC",	LLOGW,	AMULLDVCC,
489 	"MULLDV",	LLOGW,	AMULLDV,
490 	"RFID",	LRETRN,	ARFID,
491 	"HRFID", LRETRN, AHRFID,
492 	"RLDMI",	LRLWM,	ARLDMI,
493 	"RLDMICC",	LRLWM,	ARLDMICC,
494 	"RLDC",	LRLWM,	ARLDC,
495 	"RLDCCC",	LRLWM,	ARLDCCC,
496 	"RLDCR",	LRLWM,	ARLDCR,
497 	"RLDCRCC",	LRLWM,	ARLDCRCC,
498 	"RLDCL",	LRLWM,	ARLDCL,
499 	"RLDCLCC",	LRLWM,	ARLDCLCC,
500 	"SLBIA",	LNOP,	ASLBIA,
501 	"SLBIE",	LNOP,	ASLBIE,
502 	"SLBMFEE",	LABS,	ASLBMFEE,
503 	"SLBMFEV",	LABS,	ASLBMFEV,
504 	"SLBMTE",	LABS,	ASLBMTE,
505 	"SLD",	LSHW,	ASLD,
506 	"SLDCC",	LSHW,	ASLDCC,
507 	"SRD",	LSHW,	ASRD,
508 	"SRAD",	LSHW,	ASRAD,
509 	"SRADCC",	LSHW,	ASRADCC,
510 	"SRDCC",	LSHW,	ASRDCC,
511 	"STDCCC",	LXST,	ASTDCCC,
512 	"TD",	LADDW,	ATD,
513 
514 	/* pseudo instructions */
515 	"REM",	LLOGW,	AREM,
516 	"REMCC",	LLOGW,	AREMCC,
517 	"REMV",	LLOGW,	AREMV,
518 	"REMVCC",	LLOGW,	AREMVCC,
519 	"REMU",	LLOGW,	AREMU,
520 	"REMUCC",	LLOGW,	AREMUCC,
521 	"REMUV",	LLOGW,	AREMUV,
522 	"REMUVCC",	LLOGW,	AREMUVCC,
523 	"REMD",	LLOGW,	AREMD,
524 	"REMDCC",	LLOGW,	AREMDCC,
525 	"REMDV",	LLOGW,	AREMDV,
526 	"REMDVCC",	LLOGW,	AREMDVCC,
527 	"REMDU",	LLOGW,	AREMDU,
528 	"REMDUCC",	LLOGW,	AREMDUCC,
529 	"REMDUV",	LLOGW,	AREMDUV,
530 	"REMDUVCC",	LLOGW,	AREMDUVCC,
531 
532 /* special instructions */
533 	"DCBF",		LXOP,	ADCBF,
534 	"DCBI",		LXOP,	ADCBI,
535 	"DCBST",	LXOP,	ADCBST,
536 	"DCBT",		LXOP,	ADCBT,
537 	"DCBTST",	LXOP,	ADCBTST,
538 	"DCBZ",		LXOP,	ADCBZ,
539 	"ICBI",		LXOP,	AICBI,
540 
541 	"ECIWX",	LXLD,	AECIWX,
542 	"ECOWX",	LXST,	AECOWX,
543 	"LWAR", LXLD, ALWAR,
544 	"LWAR", LXLD, ALWAR,
545 	"STWCCC", LXST, ASTWCCC,
546 	"EIEIO",	LRETRN,	AEIEIO,
547 	"TLBIE",	LNOP,	ATLBIE,
548 	"TLBIEL",	LNOP,	ATLBIEL,
549 	"LSW",	LXLD, ALSW,
550 	"STSW",	LXST, ASTSW,
551 
552 	"ISYNC",	LRETRN, AISYNC,
553 	"SYNC",		LRETRN, ASYNC,
554 	"TLBSYNC",	LRETRN,	ATLBSYNC,
555 	"PTESYNC",	LRETRN,	APTESYNC,
556 /*	"TW",		LADDW,	ATW,*/
557 
558 	"WORD",		LWORD, AWORD,
559 	"DWORD",	LWORD, ADWORD,
560 	"SCHED",	LSCHED, 0,
561 	"NOSCHED",	LSCHED,	0x80,
562 
563 	0
564 };
565 
566 void
cinit(void)567 cinit(void)
568 {
569 	Sym *s;
570 	int i;
571 
572 	nullgen.sym = S;
573 	nullgen.offset = 0;
574 	nullgen.type = D_NONE;
575 	nullgen.name = D_NONE;
576 	nullgen.reg = NREG;
577 	nullgen.xreg = NREG;
578 	if(FPCHIP)
579 		nullgen.dval = 0;
580 	for(i=0; i<sizeof(nullgen.sval); i++)
581 		nullgen.sval[i] = 0;
582 
583 	nerrors = 0;
584 	iostack = I;
585 	iofree = I;
586 	peekc = IGN;
587 	nhunk = 0;
588 	for(i=0; i<NHASH; i++)
589 		hash[i] = S;
590 	for(i=0; itab[i].name; i++) {
591 		s = slookup(itab[i].name);
592 		s->type = itab[i].type;
593 		s->value = itab[i].value;
594 	}
595 	ALLOCN(pathname, 0, 100);
596 	if(mygetwd(pathname, 99) == 0) {
597 		ALLOCN(pathname, 100, 900);
598 		if(mygetwd(pathname, 999) == 0)
599 			strcpy(pathname, "/???");
600 	}
601 }
602 
603 void
syminit(Sym * s)604 syminit(Sym *s)
605 {
606 
607 	s->type = LNAME;
608 	s->value = 0;
609 }
610 
611 void
cclean(void)612 cclean(void)
613 {
614 
615 	outcode(AEND, &nullgen, NREG, &nullgen);
616 	Bflush(&obuf);
617 }
618 
619 void
zname(char * n,int t,int s)620 zname(char *n, int t, int s)
621 {
622 
623 	Bputc(&obuf, ANAME);
624 	Bputc(&obuf, ANAME>>8);
625 	Bputc(&obuf, t);	/* type */
626 	Bputc(&obuf, s);	/* sym */
627 	while(*n) {
628 		Bputc(&obuf, *n);
629 		n++;
630 	}
631 	Bputc(&obuf, 0);
632 }
633 
634 void
zaddr(Gen * a,int s)635 zaddr(Gen *a, int s)
636 {
637 	long l;
638 	int i;
639 	char *n;
640 	Ieee e;
641 
642 	if(a->type == D_CONST){
643 		l = a->offset;
644 		if((vlong)l != a->offset)
645 			a->type = D_DCONST;
646 	}
647 	Bputc(&obuf, a->type);
648 	Bputc(&obuf, a->reg);
649 	Bputc(&obuf, s);
650 	Bputc(&obuf, a->name);
651 	switch(a->type) {
652 	default:
653 		print("unknown type %d\n", a->type);
654 		exits("arg");
655 
656 	case D_NONE:
657 	case D_REG:
658 	case D_FREG:
659 	case D_CREG:
660 	case D_FPSCR:
661 	case D_MSR:
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_DCONST:
678 		l = a->offset;
679 		Bputc(&obuf, l);
680 		Bputc(&obuf, l>>8);
681 		Bputc(&obuf, l>>16);
682 		Bputc(&obuf, l>>24);
683 		l = a->offset>>32;
684 		Bputc(&obuf, l);
685 		Bputc(&obuf, l>>8);
686 		Bputc(&obuf, l>>16);
687 		Bputc(&obuf, l>>24);
688 		break;
689 
690 	case D_SCONST:
691 		n = a->sval;
692 		for(i=0; i<NSNAME; i++) {
693 			Bputc(&obuf, *n);
694 			n++;
695 		}
696 		break;
697 
698 	case D_FCONST:
699 		ieeedtod(&e, a->dval);
700 		Bputc(&obuf, e.l);
701 		Bputc(&obuf, e.l>>8);
702 		Bputc(&obuf, e.l>>16);
703 		Bputc(&obuf, e.l>>24);
704 		Bputc(&obuf, e.h);
705 		Bputc(&obuf, e.h>>8);
706 		Bputc(&obuf, e.h>>16);
707 		Bputc(&obuf, e.h>>24);
708 		break;
709 	}
710 }
711 
712 int
outsim(Gen * g)713 outsim(Gen *g)
714 {
715 	Sym *s;
716 	int sno, t;
717 
718 	s = g->sym;
719 	if(s == S)
720 		return 0;
721 	sno = s->sym;
722 	if(sno < 0 || sno >= NSYM)
723 		sno = 0;
724 	t = g->name;
725 	if(h[sno].type == t && h[sno].sym == s)
726 		return sno;
727 	zname(s->name, t, sym);
728 	s->sym = sym;
729 	h[sym].sym = s;
730 	h[sym].type = t;
731 	sno = sym;
732 	sym++;
733 	if(sym >= NSYM)
734 		sym = 1;
735 	return sno;
736 }
737 
738 void
outcode(int a,Gen * g1,int reg,Gen * g2)739 outcode(int a, Gen *g1, int reg, Gen *g2)
740 {
741 	int sf, st;
742 
743 	if(a != AGLOBL && a != ADATA)
744 		pc++;
745 	if(pass == 1)
746 		return;
747 	if(g1->xreg != NREG) {
748 		if(reg != NREG || g2->xreg != NREG)
749 			yyerror("bad addressing modes");
750 		reg = g1->xreg;
751 	} else
752 	if(g2->xreg != NREG) {
753 		if(reg != NREG)
754 			yyerror("bad addressing modes");
755 		reg = g2->xreg;
756 	}
757 	do {
758 		sf = outsim(g1);
759 		st = outsim(g2);
760 	} while(sf != 0 && st == sf);
761 	Bputc(&obuf, a);
762 	Bputc(&obuf, a>>8);
763 	Bputc(&obuf, reg|nosched);
764 	Bputc(&obuf, lineno);
765 	Bputc(&obuf, lineno>>8);
766 	Bputc(&obuf, lineno>>16);
767 	Bputc(&obuf, lineno>>24);
768 	zaddr(g1, sf);
769 	zaddr(g2, st);
770 }
771 
772 void
outgcode(int a,Gen * g1,int reg,Gen * g2,Gen * g3)773 outgcode(int a, Gen *g1, int reg, Gen *g2, Gen *g3)
774 {
775 	int s1, s2, s3, flag;
776 
777 	if(a != AGLOBL && a != ADATA)
778 		pc++;
779 	if(pass == 1)
780 		return;
781 	do {
782 		s1 = outsim(g1);
783 		s2 = outsim(g2);
784 		s3 = outsim(g3);
785 	} while(s1 && (s2 && s1 == s2 || s3 && s1 == s3) || s2 && (s3 && s2 == s3));
786 	flag = 0;
787 	if(g2->type != D_NONE)
788 		flag = 0x40;	/* flags extra operand */
789 	Bputc(&obuf, a);
790 	Bputc(&obuf, a>>8);
791 	Bputc(&obuf, reg | nosched | flag);
792 	Bputc(&obuf, lineno);
793 	Bputc(&obuf, lineno>>8);
794 	Bputc(&obuf, lineno>>16);
795 	Bputc(&obuf, lineno>>24);
796 	zaddr(g1, s1);
797 	if(flag)
798 		zaddr(g2, s2);
799 	zaddr(g3, s3);
800 }
801 
802 void
outhist(void)803 outhist(void)
804 {
805 	Gen g;
806 	Hist *h;
807 	char *p, *q, *op, c;
808 	int n;
809 
810 	g = nullgen;
811 	c = pathchar();
812 	for(h = hist; h != H; h = h->link) {
813 		p = h->name;
814 		op = 0;
815 		/* on windows skip drive specifier in pathname */
816 		if(systemtype(Windows) && p && p[1] == ':'){
817 			p += 2;
818 			c = *p;
819 		}
820 		if(p && p[0] != c && h->offset == 0 && pathname){
821 			/* on windows skip drive specifier in pathname */
822 			if(systemtype(Windows) && pathname[1] == ':') {
823 				op = p;
824 				p = pathname+2;
825 				c = *p;
826 			} else if(pathname[0] == c){
827 				op = p;
828 				p = pathname;
829 			}
830 		}
831 		while(p) {
832 			q = strchr(p, c);
833 			if(q) {
834 				n = q-p;
835 				if(n == 0){
836 					n = 1;	/* leading "/" */
837 					*p = '/';	/* don't emit "\" on windows */
838 				}
839 				q++;
840 			} else {
841 				n = strlen(p);
842 				q = 0;
843 			}
844 			if(n) {
845 				Bputc(&obuf, ANAME);
846 				Bputc(&obuf, ANAME>>8);
847 				Bputc(&obuf, D_FILE);	/* type */
848 				Bputc(&obuf, 1);	/* sym */
849 				Bputc(&obuf, '<');
850 				Bwrite(&obuf, p, n);
851 				Bputc(&obuf, 0);
852 			}
853 			p = q;
854 			if(p == 0 && op) {
855 				p = op;
856 				op = 0;
857 			}
858 		}
859 		g.offset = h->offset;
860 
861 		Bputc(&obuf, AHISTORY);
862 		Bputc(&obuf, AHISTORY>>8);
863 		Bputc(&obuf, 0);
864 		Bputc(&obuf, h->line);
865 		Bputc(&obuf, h->line>>8);
866 		Bputc(&obuf, h->line>>16);
867 		Bputc(&obuf, h->line>>24);
868 		zaddr(&nullgen, 0);
869 		zaddr(&g, 0);
870 	}
871 }
872 
873 #include "../cc/lexbody"
874 #include "../cc/macbody"
875 #include "../cc/compat"
876