xref: /inferno-os/utils/8a/lex.c (revision e45fa0eb0763b57d6fb0649c064bc3b95ccdea6c)
1 #include <ctype.h>
2 #define	EXTERN
3 #include "a.h"
4 #include "y.tab.h"
5 
6 void
7 main(int argc, char *argv[])
8 {
9 	char *p;
10 	int nout, nproc, status, i, c;
11 
12 	thechar = '8';
13 	thestring = "386";
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 && !systemtype(Windows)) {
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 	p = utfrrune(ofile, pathchar());
100 	if(p) {
101 		include[0] = ofile;
102 		*p++ = 0;
103 	} else
104 		p = ofile;
105 	if(outfile == 0) {
106 		outfile = p;
107 		if(outfile){
108 			p = utfrrune(outfile, '.');
109 			if(p)
110 				if(p[1] == 's' && p[2] == 0)
111 					p[0] = 0;
112 			p = utfrune(outfile, 0);
113 			p[0] = '.';
114 			p[1] = thechar;
115 			p[2] = 0;
116 		} else
117 			outfile = "/dev/null";
118 	}
119 	p = getenv("INCLUDE");
120 	if(p) {
121 		setinclude(p);
122 	} else {
123 		if(systemtype(Plan9)) {
124 			sprint(incfile,"/%s/include", thestring);
125 			setinclude(strdup(incfile));
126 		}
127 	}
128 
129 	of = mycreat(outfile, 0664);
130 	if(of < 0) {
131 		yyerror("%ca: cannot create %s", thechar, outfile);
132 		errorexit();
133 	}
134 	Binit(&obuf, of, OWRITE);
135 
136 	pass = 1;
137 	pinit(file);
138 	for(i=0; i<nDlist; i++)
139 		dodefine(Dlist[i]);
140 	yyparse();
141 	if(nerrors) {
142 		cclean();
143 		return nerrors;
144 	}
145 
146 	pass = 2;
147 	outhist();
148 	pinit(file);
149 	for(i=0; i<nDlist; i++)
150 		dodefine(Dlist[i]);
151 	yyparse();
152 	cclean();
153 	return nerrors;
154 }
155 
156 struct
157 {
158 	char	*name;
159 	ushort	type;
160 	ushort	value;
161 } itab[] =
162 {
163 	"SP",		LSP,	D_AUTO,
164 	"SB",		LSB,	D_EXTERN,
165 	"FP",		LFP,	D_PARAM,
166 	"PC",		LPC,	D_BRANCH,
167 
168 	"AL",		LBREG,	D_AL,
169 	"CL",		LBREG,	D_CL,
170 	"DL",		LBREG,	D_DL,
171 	"BL",		LBREG,	D_BL,
172 	"AH",		LBREG,	D_AH,
173 	"CH",		LBREG,	D_CH,
174 	"DH",		LBREG,	D_DH,
175 	"BH",		LBREG,	D_BH,
176 
177 	"AX",		LLREG,	D_AX,
178 	"CX",		LLREG,	D_CX,
179 	"DX",		LLREG,	D_DX,
180 	"BX",		LLREG,	D_BX,
181 /*	"SP",		LLREG,	D_SP,	*/
182 	"BP",		LLREG,	D_BP,
183 	"SI",		LLREG,	D_SI,
184 	"DI",		LLREG,	D_DI,
185 
186 	"F0",		LFREG,	D_F0+0,
187 	"F1",		LFREG,	D_F0+1,
188 	"F2",		LFREG,	D_F0+2,
189 	"F3",		LFREG,	D_F0+3,
190 	"F4",		LFREG,	D_F0+4,
191 	"F5",		LFREG,	D_F0+5,
192 	"F6",		LFREG,	D_F0+6,
193 	"F7",		LFREG,	D_F0+7,
194 
195 	"CS",		LSREG,	D_CS,
196 	"SS",		LSREG,	D_SS,
197 	"DS",		LSREG,	D_DS,
198 	"ES",		LSREG,	D_ES,
199 	"FS",		LSREG,	D_FS,
200 	"GS",		LSREG,	D_GS,
201 
202 	"GDTR",		LBREG,	D_GDTR,
203 	"IDTR",		LBREG,	D_IDTR,
204 	"LDTR",		LBREG,	D_LDTR,
205 	"MSW",		LBREG,	D_MSW,
206 	"TASK",		LBREG,	D_TASK,
207 
208 	"CR0",		LBREG,	D_CR+0,
209 	"CR1",		LBREG,	D_CR+1,
210 	"CR2",		LBREG,	D_CR+2,
211 	"CR3",		LBREG,	D_CR+3,
212 	"CR4",		LBREG,	D_CR+4,
213 	"CR5",		LBREG,	D_CR+5,
214 	"CR6",		LBREG,	D_CR+6,
215 	"CR7",		LBREG,	D_CR+7,
216 
217 	"DR0",		LBREG,	D_DR+0,
218 	"DR1",		LBREG,	D_DR+1,
219 	"DR2",		LBREG,	D_DR+2,
220 	"DR3",		LBREG,	D_DR+3,
221 	"DR4",		LBREG,	D_DR+4,
222 	"DR5",		LBREG,	D_DR+5,
223 	"DR6",		LBREG,	D_DR+6,
224 	"DR7",		LBREG,	D_DR+7,
225 
226 	"TR0",		LBREG,	D_TR+0,
227 	"TR1",		LBREG,	D_TR+1,
228 	"TR2",		LBREG,	D_TR+2,
229 	"TR3",		LBREG,	D_TR+3,
230 	"TR4",		LBREG,	D_TR+4,
231 	"TR5",		LBREG,	D_TR+5,
232 	"TR6",		LBREG,	D_TR+6,
233 	"TR7",		LBREG,	D_TR+7,
234 
235 	"AAA",		LTYPE0,	AAAA,
236 	"AAD",		LTYPE0,	AAAD,
237 	"AAM",		LTYPE0,	AAAM,
238 	"AAS",		LTYPE0,	AAAS,
239 	"ADCB",		LTYPE3,	AADCB,
240 	"ADCL",		LTYPE3,	AADCL,
241 	"ADCW",		LTYPE3,	AADCW,
242 	"ADDB",		LTYPE3,	AADDB,
243 	"ADDL",		LTYPE3,	AADDL,
244 	"ADDW",		LTYPE3,	AADDW,
245 	"ADJSP",	LTYPE2,	AADJSP,
246 	"ANDB",		LTYPE3,	AANDB,
247 	"ANDL",		LTYPE3,	AANDL,
248 	"ANDW",		LTYPE3,	AANDW,
249 	"ARPL",		LTYPE3,	AARPL,
250 	"BOUNDL",	LTYPE3,	ABOUNDL,
251 	"BOUNDW",	LTYPE3,	ABOUNDW,
252 	"BSFL",		LTYPE3,	ABSFL,
253 	"BSFW",		LTYPE3,	ABSFW,
254 	"BSRL",		LTYPE3,	ABSRL,
255 	"BSRW",		LTYPE3,	ABSRW,
256 	"BTCL",		LTYPE3,	ABTCL,
257 	"BTCW",		LTYPE3,	ABTCW,
258 	"BTL",		LTYPE3,	ABTL,
259 	"BTRL",		LTYPE3,	ABTRL,
260 	"BTRW",		LTYPE3,	ABTRW,
261 	"BTSL",		LTYPE3,	ABTSL,
262 	"BTSW",		LTYPE3,	ABTSW,
263 	"BTW",		LTYPE3,	ABTW,
264 	"BYTE",		LTYPE2,	ABYTE,
265 	"CALL",		LTYPEC,	ACALL,
266 	"CLC",		LTYPE0,	ACLC,
267 	"CLD",		LTYPE0,	ACLD,
268 	"CLI",		LTYPE0,	ACLI,
269 	"CLTS",		LTYPE0,	ACLTS,
270 	"CMC",		LTYPE0,	ACMC,
271 	"CMPB",		LTYPE4,	ACMPB,
272 	"CMPL",		LTYPE4,	ACMPL,
273 	"CMPW",		LTYPE4,	ACMPW,
274 	"CMPSB",	LTYPE0,	ACMPSB,
275 	"CMPSL",	LTYPE0,	ACMPSL,
276 	"CMPSW",	LTYPE0,	ACMPSW,
277 	"CMPXCHGB",	LTYPE3,	ACMPXCHGB,
278 	"CMPXCHGL",	LTYPE3,	ACMPXCHGL,
279 	"CMPXCHGW",	LTYPE3,	ACMPXCHGW,
280 	"DAA",		LTYPE0,	ADAA,
281 	"DAS",		LTYPE0,	ADAS,
282 	"DATA",		LTYPED,	ADATA,
283 	"DECB",		LTYPE1,	ADECB,
284 	"DECL",		LTYPE1,	ADECL,
285 	"DECW",		LTYPE1,	ADECW,
286 	"DIVB",		LTYPE2,	ADIVB,
287 	"DIVL",		LTYPE2,	ADIVL,
288 	"DIVW",		LTYPE2,	ADIVW,
289 	"END",		LTYPE0,	AEND,
290 	"ENTER",	LTYPE2,	AENTER,
291 	"GLOBL",	LTYPEG,	AGLOBL,
292 	"HLT",		LTYPE0,	AHLT,
293 	"IDIVB",	LTYPE2,	AIDIVB,
294 	"IDIVL",	LTYPE2,	AIDIVL,
295 	"IDIVW",	LTYPE2,	AIDIVW,
296 	"IMULB",	LTYPEI,	AIMULB,
297 	"IMULL",	LTYPEI,	AIMULL,
298 	"IMULW",	LTYPEI,	AIMULW,
299 	"INB",		LTYPE0,	AINB,
300 	"INL",		LTYPE0,	AINL,
301 	"INW",		LTYPE0,	AINW,
302 	"INCB",		LTYPE1,	AINCB,
303 	"INCL",		LTYPE1,	AINCL,
304 	"INCW",		LTYPE1,	AINCW,
305 	"INSB",		LTYPE0,	AINSB,
306 	"INSL",		LTYPE0,	AINSL,
307 	"INSW",		LTYPE0,	AINSW,
308 	"INT",		LTYPE2,	AINT,
309 	"INTO",		LTYPE0,	AINTO,
310 	"IRETL",	LTYPE0,	AIRETL,
311 	"IRETW",	LTYPE0,	AIRETW,
312 
313 	"JOS",		LTYPER,	AJOS,
314 	"JO",		LTYPER,	AJOS,	/* alternate */
315 	"JOC",		LTYPER,	AJOC,
316 	"JNO",		LTYPER,	AJOC,	/* alternate */
317 	"JCS",		LTYPER,	AJCS,
318 	"JB",		LTYPER,	AJCS,	/* alternate */
319 	"JC",		LTYPER,	AJCS,	/* alternate */
320 	"JNAE",		LTYPER,	AJCS,	/* alternate */
321 	"JLO",		LTYPER,	AJCS,	/* alternate */
322 	"JCC",		LTYPER,	AJCC,
323 	"JAE",		LTYPER,	AJCC,	/* alternate */
324 	"JNB",		LTYPER,	AJCC,	/* alternate */
325 	"JNC",		LTYPER,	AJCC,	/* alternate */
326 	"JHS",		LTYPER,	AJCC,	/* alternate */
327 	"JEQ",		LTYPER,	AJEQ,
328 	"JE",		LTYPER,	AJEQ,	/* alternate */
329 	"JZ",		LTYPER,	AJEQ,	/* alternate */
330 	"JNE",		LTYPER,	AJNE,
331 	"JNZ",		LTYPER,	AJNE,	/* alternate */
332 	"JLS",		LTYPER,	AJLS,
333 	"JBE",		LTYPER,	AJLS,	/* alternate */
334 	"JNA",		LTYPER,	AJLS,	/* alternate */
335 	"JHI",		LTYPER,	AJHI,
336 	"JA",		LTYPER,	AJHI,	/* alternate */
337 	"JNBE",		LTYPER,	AJHI,	/* alternate */
338 	"JMI",		LTYPER,	AJMI,
339 	"JS",		LTYPER,	AJMI,	/* alternate */
340 	"JPL",		LTYPER,	AJPL,
341 	"JNS",		LTYPER,	AJPL,	/* alternate */
342 	"JPS",		LTYPER,	AJPS,
343 	"JP",		LTYPER,	AJPS,	/* alternate */
344 	"JPE",		LTYPER,	AJPS,	/* alternate */
345 	"JPC",		LTYPER,	AJPC,
346 	"JNP",		LTYPER,	AJPC,	/* alternate */
347 	"JPO",		LTYPER,	AJPC,	/* alternate */
348 	"JLT",		LTYPER,	AJLT,
349 	"JL",		LTYPER,	AJLT,	/* alternate */
350 	"JNGE",		LTYPER,	AJLT,	/* alternate */
351 	"JGE",		LTYPER,	AJGE,
352 	"JNL",		LTYPER,	AJGE,	/* alternate */
353 	"JLE",		LTYPER,	AJLE,
354 	"JNG",		LTYPER,	AJLE,	/* alternate */
355 	"JGT",		LTYPER,	AJGT,
356 	"JG",		LTYPER,	AJGT,	/* alternate */
357 	"JNLE",		LTYPER,	AJGT,	/* alternate */
358 
359 	"JCXZ",		LTYPER,	AJCXZ,
360 	"JMP",		LTYPEC,	AJMP,
361 	"LAHF",		LTYPE0,	ALAHF,
362 	"LARL",		LTYPE3,	ALARL,
363 	"LARW",		LTYPE3,	ALARW,
364 	"LEAL",		LTYPE3,	ALEAL,
365 	"LEAW",		LTYPE3,	ALEAW,
366 	"LEAVEL",	LTYPE0,	ALEAVEL,
367 	"LEAVEW",	LTYPE0,	ALEAVEW,
368 	"LOCK",		LTYPE0,	ALOCK,
369 	"LODSB",	LTYPE0,	ALODSB,
370 	"LODSL",	LTYPE0,	ALODSL,
371 	"LODSW",	LTYPE0,	ALODSW,
372 	"LONG",		LTYPE2,	ALONG,
373 	"LOOP",		LTYPER,	ALOOP,
374 	"LOOPEQ",	LTYPER,	ALOOPEQ,
375 	"LOOPNE",	LTYPER,	ALOOPNE,
376 	"LSLL",		LTYPE3,	ALSLL,
377 	"LSLW",		LTYPE3,	ALSLW,
378 	"MOVB",		LTYPE3,	AMOVB,
379 	"MOVL",		LTYPEM,	AMOVL,
380 	"MOVW",		LTYPEM,	AMOVW,
381 	"MOVBLSX",	LTYPE3, AMOVBLSX,
382 	"MOVBLZX",	LTYPE3, AMOVBLZX,
383 	"MOVBWSX",	LTYPE3, AMOVBWSX,
384 	"MOVBWZX",	LTYPE3, AMOVBWZX,
385 	"MOVWLSX",	LTYPE3, AMOVWLSX,
386 	"MOVWLZX",	LTYPE3, AMOVWLZX,
387 	"MOVSB",	LTYPE0,	AMOVSB,
388 	"MOVSL",	LTYPE0,	AMOVSL,
389 	"MOVSW",	LTYPE0,	AMOVSW,
390 	"MULB",		LTYPE2,	AMULB,
391 	"MULL",		LTYPE2,	AMULL,
392 	"MULW",		LTYPE2,	AMULW,
393 	"NEGB",		LTYPE1,	ANEGB,
394 	"NEGL",		LTYPE1,	ANEGL,
395 	"NEGW",		LTYPE1,	ANEGW,
396 	"NOP",		LTYPEN,	ANOP,
397 	"NOTB",		LTYPE1,	ANOTB,
398 	"NOTL",		LTYPE1,	ANOTL,
399 	"NOTW",		LTYPE1,	ANOTW,
400 	"ORB",		LTYPE3,	AORB,
401 	"ORL",		LTYPE3,	AORL,
402 	"ORW",		LTYPE3,	AORW,
403 	"OUTB",		LTYPE0,	AOUTB,
404 	"OUTL",		LTYPE0,	AOUTL,
405 	"OUTW",		LTYPE0,	AOUTW,
406 	"OUTSB",	LTYPE0,	AOUTSB,
407 	"OUTSL",	LTYPE0,	AOUTSL,
408 	"OUTSW",	LTYPE0,	AOUTSW,
409 	"POPAL",	LTYPE0,	APOPAL,
410 	"POPAW",	LTYPE0,	APOPAW,
411 	"POPFL",	LTYPE0,	APOPFL,
412 	"POPFW",	LTYPE0,	APOPFW,
413 	"POPL",		LTYPE1,	APOPL,
414 	"POPW",		LTYPE1,	APOPW,
415 	"PUSHAL",	LTYPE0,	APUSHAL,
416 	"PUSHAW",	LTYPE0,	APUSHAW,
417 	"PUSHFL",	LTYPE0,	APUSHFL,
418 	"PUSHFW",	LTYPE0,	APUSHFW,
419 	"PUSHL",	LTYPE2,	APUSHL,
420 	"PUSHW",	LTYPE2,	APUSHW,
421 	"RCLB",		LTYPE3,	ARCLB,
422 	"RCLL",		LTYPE3,	ARCLL,
423 	"RCLW",		LTYPE3,	ARCLW,
424 	"RCRB",		LTYPE3,	ARCRB,
425 	"RCRL",		LTYPE3,	ARCRL,
426 	"RCRW",		LTYPE3,	ARCRW,
427 	"REP",		LTYPE0,	AREP,
428 	"REPN",		LTYPE0,	AREPN,
429 	"RET",		LTYPE0,	ARET,
430 	"ROLB",		LTYPE3,	AROLB,
431 	"ROLL",		LTYPE3,	AROLL,
432 	"ROLW",		LTYPE3,	AROLW,
433 	"RORB",		LTYPE3,	ARORB,
434 	"RORL",		LTYPE3,	ARORL,
435 	"RORW",		LTYPE3,	ARORW,
436 	"SAHF",		LTYPE0,	ASAHF,
437 	"SALB",		LTYPE3,	ASALB,
438 	"SALL",		LTYPE3,	ASALL,
439 	"SALW",		LTYPE3,	ASALW,
440 	"SARB",		LTYPE3,	ASARB,
441 	"SARL",		LTYPE3,	ASARL,
442 	"SARW",		LTYPE3,	ASARW,
443 	"SBBB",		LTYPE3,	ASBBB,
444 	"SBBL",		LTYPE3,	ASBBL,
445 	"SBBW",		LTYPE3,	ASBBW,
446 	"SCASB",	LTYPE0,	ASCASB,
447 	"SCASL",	LTYPE0,	ASCASL,
448 	"SCASW",	LTYPE0,	ASCASW,
449 	"SETCC",	LTYPE1,	ASETCC,
450 	"SETCS",	LTYPE1,	ASETCS,
451 	"SETEQ",	LTYPE1,	ASETEQ,
452 	"SETGE",	LTYPE1,	ASETGE,
453 	"SETGT",	LTYPE1,	ASETGT,
454 	"SETHI",	LTYPE1,	ASETHI,
455 	"SETLE",	LTYPE1,	ASETLE,
456 	"SETLS",	LTYPE1,	ASETLS,
457 	"SETLT",	LTYPE1,	ASETLT,
458 	"SETMI",	LTYPE1,	ASETMI,
459 	"SETNE",	LTYPE1,	ASETNE,
460 	"SETOC",	LTYPE1,	ASETOC,
461 	"SETOS",	LTYPE1,	ASETOS,
462 	"SETPC",	LTYPE1,	ASETPC,
463 	"SETPL",	LTYPE1,	ASETPL,
464 	"SETPS",	LTYPE1,	ASETPS,
465 	"CDQ",		LTYPE0,	ACDQ,
466 	"CWD",		LTYPE0,	ACWD,
467 	"SHLB",		LTYPE3,	ASHLB,
468 	"SHLL",		LTYPES,	ASHLL,
469 	"SHLW",		LTYPES,	ASHLW,
470 	"SHRB",		LTYPE3,	ASHRB,
471 	"SHRL",		LTYPES,	ASHRL,
472 	"SHRW",		LTYPES,	ASHRW,
473 	"STC",		LTYPE0,	ASTC,
474 	"STD",		LTYPE0,	ASTD,
475 	"STI",		LTYPE0,	ASTI,
476 	"STOSB",	LTYPE0,	ASTOSB,
477 	"STOSL",	LTYPE0,	ASTOSL,
478 	"STOSW",	LTYPE0,	ASTOSW,
479 	"SUBB",		LTYPE3,	ASUBB,
480 	"SUBL",		LTYPE3,	ASUBL,
481 	"SUBW",		LTYPE3,	ASUBW,
482 	"SYSCALL",	LTYPE0,	ASYSCALL,
483 	"TESTB",	LTYPE3,	ATESTB,
484 	"TESTL",	LTYPE3,	ATESTL,
485 	"TESTW",	LTYPE3,	ATESTW,
486 	"TEXT",		LTYPET,	ATEXT,
487 	"VERR",		LTYPE2,	AVERR,
488 	"VERW",		LTYPE2,	AVERW,
489 	"WAIT",		LTYPE0,	AWAIT,
490 	"WORD",		LTYPE2,	AWORD,
491 	"XCHGB",	LTYPE3,	AXCHGB,
492 	"XCHGL",	LTYPE3,	AXCHGL,
493 	"XCHGW",	LTYPE3,	AXCHGW,
494 	"XLAT",		LTYPE2,	AXLAT,
495 	"XORB",		LTYPE3,	AXORB,
496 	"XORL",		LTYPE3,	AXORL,
497 	"XORW",		LTYPE3,	AXORW,
498 
499 	"CMOVLCC",	LTYPE3,	ACMOVLCC,
500 	"CMOVLCS",	LTYPE3,	ACMOVLCS,
501 	"CMOVLEQ",	LTYPE3,	ACMOVLEQ,
502 	"CMOVLGE",	LTYPE3,	ACMOVLGE,
503 	"CMOVLGT",	LTYPE3,	ACMOVLGT,
504 	"CMOVLHI",	LTYPE3,	ACMOVLHI,
505 	"CMOVLLE",	LTYPE3,	ACMOVLLE,
506 	"CMOVLLS",	LTYPE3,	ACMOVLLS,
507 	"CMOVLLT",	LTYPE3,	ACMOVLLT,
508 	"CMOVLMI",	LTYPE3,	ACMOVLMI,
509 	"CMOVLNE",	LTYPE3,	ACMOVLNE,
510 	"CMOVLOC",	LTYPE3,	ACMOVLOC,
511 	"CMOVLOS",	LTYPE3,	ACMOVLOS,
512 	"CMOVLPC",	LTYPE3,	ACMOVLPC,
513 	"CMOVLPL",	LTYPE3,	ACMOVLPL,
514 	"CMOVLPS",	LTYPE3,	ACMOVLPS,
515 	"CMOVWCC",	LTYPE3,	ACMOVWCC,
516 	"CMOVWCS",	LTYPE3,	ACMOVWCS,
517 	"CMOVWEQ",	LTYPE3,	ACMOVWEQ,
518 	"CMOVWGE",	LTYPE3,	ACMOVWGE,
519 	"CMOVWGT",	LTYPE3,	ACMOVWGT,
520 	"CMOVWHI",	LTYPE3,	ACMOVWHI,
521 	"CMOVWLE",	LTYPE3,	ACMOVWLE,
522 	"CMOVWLS",	LTYPE3,	ACMOVWLS,
523 	"CMOVWLT",	LTYPE3,	ACMOVWLT,
524 	"CMOVWMI",	LTYPE3,	ACMOVWMI,
525 	"CMOVWNE",	LTYPE3,	ACMOVWNE,
526 	"CMOVWOC",	LTYPE3,	ACMOVWOC,
527 	"CMOVWOS",	LTYPE3,	ACMOVWOS,
528 	"CMOVWPC",	LTYPE3,	ACMOVWPC,
529 	"CMOVWPL",	LTYPE3,	ACMOVWPL,
530 	"CMOVWPS",	LTYPE3,	ACMOVWPS,
531 
532 	"FMOVB",	LTYPE3, AFMOVB,
533 	"FMOVBP",	LTYPE3, AFMOVBP,
534 	"FMOVD",	LTYPE3, AFMOVD,
535 	"FMOVDP",	LTYPE3, AFMOVDP,
536 	"FMOVF",	LTYPE3, AFMOVF,
537 	"FMOVFP",	LTYPE3, AFMOVFP,
538 	"FMOVL",	LTYPE3, AFMOVL,
539 	"FMOVLP",	LTYPE3, AFMOVLP,
540 	"FMOVV",	LTYPE3, AFMOVV,
541 	"FMOVVP",	LTYPE3, AFMOVVP,
542 	"FMOVW",	LTYPE3, AFMOVW,
543 	"FMOVWP",	LTYPE3, AFMOVWP,
544 	"FMOVX",	LTYPE3, AFMOVX,
545 	"FMOVXP",	LTYPE3, AFMOVXP,
546 	"FCMOVCC",	LTYPE3, AFCMOVCC,
547 	"FCMOVCS",	LTYPE3, AFCMOVCS,
548 	"FCMOVEQ",	LTYPE3, AFCMOVEQ,
549 	"FCMOVHI",	LTYPE3, AFCMOVHI,
550 	"FCMOVLS",	LTYPE3, AFCMOVLS,
551 	"FCMOVNE",	LTYPE3, AFCMOVNE,
552 	"FCMOVNU",	LTYPE3, AFCMOVNU,
553 	"FCMOVUN",	LTYPE3, AFCMOVUN,
554 	"FCOMB",	LTYPE3, AFCOMB,
555 	"FCOMBP",	LTYPE3, AFCOMBP,
556 	"FCOMD",	LTYPE3, AFCOMD,
557 	"FCOMDP",	LTYPE3, AFCOMDP,
558 	"FCOMDPP",	LTYPE3, AFCOMDPP,
559 	"FCOMF",	LTYPE3, AFCOMF,
560 	"FCOMFP",	LTYPE3, AFCOMFP,
561 	"FCOMI",	LTYPE3, AFCOMI,
562 	"FCOMIP",	LTYPE3, AFCOMIP,
563 	"FCOML",	LTYPE3, AFCOML,
564 	"FCOMLP",	LTYPE3, AFCOMLP,
565 	"FCOMW",	LTYPE3, AFCOMW,
566 	"FCOMWP",	LTYPE3, AFCOMWP,
567 	"FUCOM",	LTYPE3, AFUCOM,
568 	"FUCOMI",	LTYPE3, AFUCOMI,
569 	"FUCOMIP",	LTYPE3, AFUCOMIP,
570 	"FUCOMP",	LTYPE3, AFUCOMP,
571 	"FUCOMPP",	LTYPE3, AFUCOMPP,
572 	"FADDW",	LTYPE3, AFADDW,
573 	"FADDL",	LTYPE3, AFADDL,
574 	"FADDF",	LTYPE3, AFADDF,
575 	"FADDD",	LTYPE3, AFADDD,
576 	"FADDDP",	LTYPE3, AFADDDP,
577 	"FSUBDP",	LTYPE3, AFSUBDP,
578 	"FSUBW",	LTYPE3, AFSUBW,
579 	"FSUBL",	LTYPE3, AFSUBL,
580 	"FSUBF",	LTYPE3, AFSUBF,
581 	"FSUBD",	LTYPE3, AFSUBD,
582 	"FSUBRDP",	LTYPE3, AFSUBRDP,
583 	"FSUBRW",	LTYPE3, AFSUBRW,
584 	"FSUBRL",	LTYPE3, AFSUBRL,
585 	"FSUBRF",	LTYPE3, AFSUBRF,
586 	"FSUBRD",	LTYPE3, AFSUBRD,
587 	"FMULDP",	LTYPE3, AFMULDP,
588 	"FMULW",	LTYPE3, AFMULW,
589 	"FMULL",	LTYPE3, AFMULL,
590 	"FMULF",	LTYPE3, AFMULF,
591 	"FMULD",	LTYPE3, AFMULD,
592 	"FDIVDP",	LTYPE3, AFDIVDP,
593 	"FDIVW",	LTYPE3, AFDIVW,
594 	"FDIVL",	LTYPE3, AFDIVL,
595 	"FDIVF",	LTYPE3, AFDIVF,
596 	"FDIVD",	LTYPE3, AFDIVD,
597 	"FDIVRDP",	LTYPE3, AFDIVRDP,
598 	"FDIVRW",	LTYPE3, AFDIVRW,
599 	"FDIVRL",	LTYPE3, AFDIVRL,
600 	"FDIVRF",	LTYPE3, AFDIVRF,
601 	"FDIVRD",	LTYPE3, AFDIVRD,
602 	"FXCHD",	LTYPE3, AFXCHD,
603 	"FFREE",	LTYPE1, AFFREE,
604 	"FLDCW",	LTYPE2, AFLDCW,
605 	"FLDENV",	LTYPE1, AFLDENV,
606 	"FRSTOR",	LTYPE2, AFRSTOR,
607 	"FSAVE",	LTYPE1, AFSAVE,
608 	"FSTCW",	LTYPE1, AFSTCW,
609 	"FSTENV",	LTYPE1, AFSTENV,
610 	"FSTSW",	LTYPE1, AFSTSW,
611 	"F2XM1",	LTYPE0, AF2XM1,
612 	"FABS",		LTYPE0, AFABS,
613 	"FCHS",		LTYPE0, AFCHS,
614 	"FCLEX",	LTYPE0, AFCLEX,
615 	"FCOS",		LTYPE0, AFCOS,
616 	"FDECSTP",	LTYPE0, AFDECSTP,
617 	"FINCSTP",	LTYPE0, AFINCSTP,
618 	"FINIT",	LTYPE0, AFINIT,
619 	"FLD1",		LTYPE0, AFLD1,
620 	"FLDL2E",	LTYPE0, AFLDL2E,
621 	"FLDL2T",	LTYPE0, AFLDL2T,
622 	"FLDLG2",	LTYPE0, AFLDLG2,
623 	"FLDLN2",	LTYPE0, AFLDLN2,
624 	"FLDPI",	LTYPE0, AFLDPI,
625 	"FLDZ",		LTYPE0, AFLDZ,
626 	"FNOP",		LTYPE0, AFNOP,
627 	"FPATAN",	LTYPE0, AFPATAN,
628 	"FPREM",	LTYPE0, AFPREM,
629 	"FPREM1",	LTYPE0, AFPREM1,
630 	"FPTAN",	LTYPE0, AFPTAN,
631 	"FRNDINT",	LTYPE0, AFRNDINT,
632 	"FSCALE",	LTYPE0, AFSCALE,
633 	"FSIN",		LTYPE0, AFSIN,
634 	"FSINCOS",	LTYPE0, AFSINCOS,
635 	"FSQRT",	LTYPE0, AFSQRT,
636 	"FTST",		LTYPE0, AFTST,
637 	"FXAM",		LTYPE0, AFXAM,
638 	"FXTRACT",	LTYPE0, AFXTRACT,
639 	"FYL2X",	LTYPE0, AFYL2X,
640 	"FYL2XP1",	LTYPE0, AFYL2XP1,
641 
642 	0
643 };
644 
645 void
646 cinit(void)
647 {
648 	Sym *s;
649 	int i;
650 
651 	nullgen.sym = S;
652 	nullgen.offset = 0;
653 	if(FPCHIP)
654 		nullgen.dval = 0;
655 	for(i=0; i<sizeof(nullgen.sval); i++)
656 		nullgen.sval[i] = 0;
657 	nullgen.type = D_NONE;
658 	nullgen.index = D_NONE;
659 	nullgen.scale = 0;
660 
661 	nerrors = 0;
662 	iostack = I;
663 	iofree = I;
664 	peekc = IGN;
665 	nhunk = 0;
666 	for(i=0; i<NHASH; i++)
667 		hash[i] = S;
668 	for(i=0; itab[i].name; i++) {
669 		s = slookup(itab[i].name);
670 		if(s->type != LNAME)
671 			yyerror("double initialization %s", itab[i].name);
672 		s->type = itab[i].type;
673 		s->value = itab[i].value;
674 	}
675 
676 	pathname = allocn(pathname, 0, 100);
677 	if(mygetwd(pathname, 99) == 0) {
678 		pathname = allocn(pathname, 100, 900);
679 		if(mygetwd(pathname, 999) == 0)
680 			strcpy(pathname, "/?");
681 	}
682 }
683 
684 void
685 checkscale(int scale)
686 {
687 
688 	switch(scale) {
689 	case 1:
690 	case 2:
691 	case 4:
692 	case 8:
693 		return;
694 	}
695 	yyerror("scale must be 1248: %d", scale);
696 }
697 
698 void
699 syminit(Sym *s)
700 {
701 
702 	s->type = LNAME;
703 	s->value = 0;
704 }
705 
706 void
707 cclean(void)
708 {
709 	Gen2 g2;
710 
711 	g2.from = nullgen;
712 	g2.to = nullgen;
713 	outcode(AEND, &g2);
714 	Bflush(&obuf);
715 }
716 
717 void
718 zname(char *n, int t, int s)
719 {
720 
721 	Bputc(&obuf, ANAME);		/* as(2) */
722 	Bputc(&obuf, ANAME>>8);
723 	Bputc(&obuf, t);		/* type */
724 	Bputc(&obuf, s);		/* sym */
725 	while(*n) {
726 		Bputc(&obuf, *n);
727 		n++;
728 	}
729 	Bputc(&obuf, 0);
730 }
731 
732 void
733 zaddr(Gen *a, int s)
734 {
735 	long l;
736 	int i, t;
737 	char *n;
738 	Ieee e;
739 
740 	t = 0;
741 	if(a->index != D_NONE || a->scale != 0)
742 		t |= T_INDEX;
743 	if(a->offset != 0)
744 		t |= T_OFFSET;
745 	if(s != 0)
746 		t |= T_SYM;
747 
748 	switch(a->type) {
749 	default:
750 		t |= T_TYPE;
751 		break;
752 	case D_FCONST:
753 		t |= T_FCONST;
754 		break;
755 	case D_CONST2:
756 		t |= T_OFFSET|T_OFFSET2;
757 		break;
758 	case D_SCONST:
759 		t |= T_SCONST;
760 		break;
761 	case D_NONE:
762 		break;
763 	}
764 	Bputc(&obuf, t);
765 
766 	if(t & T_INDEX) {	/* implies index, scale */
767 		Bputc(&obuf, a->index);
768 		Bputc(&obuf, a->scale);
769 	}
770 	if(t & T_OFFSET) {	/* implies offset */
771 		l = a->offset;
772 		Bputc(&obuf, l);
773 		Bputc(&obuf, l>>8);
774 		Bputc(&obuf, l>>16);
775 		Bputc(&obuf, l>>24);
776 	}
777 	if(t & T_OFFSET2) {
778 		l = a->offset2;
779 		Bputc(&obuf, l);
780 		Bputc(&obuf, l>>8);
781 		Bputc(&obuf, l>>16);
782 		Bputc(&obuf, l>>24);
783 	}
784 	if(t & T_SYM)		/* implies sym */
785 		Bputc(&obuf, s);
786 	if(t & T_FCONST) {
787 		ieeedtod(&e, a->dval);
788 		l = e.l;
789 		Bputc(&obuf, l);
790 		Bputc(&obuf, l>>8);
791 		Bputc(&obuf, l>>16);
792 		Bputc(&obuf, l>>24);
793 		l = e.h;
794 		Bputc(&obuf, l);
795 		Bputc(&obuf, l>>8);
796 		Bputc(&obuf, l>>16);
797 		Bputc(&obuf, l>>24);
798 		return;
799 	}
800 	if(t & T_SCONST) {
801 		n = a->sval;
802 		for(i=0; i<NSNAME; i++) {
803 			Bputc(&obuf, *n);
804 			n++;
805 		}
806 		return;
807 	}
808 	if(t & T_TYPE)
809 		Bputc(&obuf, a->type);
810 }
811 
812 void
813 outcode(int a, Gen2 *g2)
814 {
815 	int sf, st, t;
816 	Sym *s;
817 
818 	if(pass == 1)
819 		goto out;
820 
821 jackpot:
822 	sf = 0;
823 	s = g2->from.sym;
824 	while(s != S) {
825 		sf = s->sym;
826 		if(sf < 0 || sf >= NSYM)
827 			sf = 0;
828 		t = g2->from.type;
829 		if(t == D_ADDR)
830 			t = g2->from.index;
831 		if(h[sf].type == t)
832 		if(h[sf].sym == s)
833 			break;
834 		zname(s->name, t, sym);
835 		s->sym = sym;
836 		h[sym].sym = s;
837 		h[sym].type = t;
838 		sf = sym;
839 		sym++;
840 		if(sym >= NSYM)
841 			sym = 1;
842 		break;
843 	}
844 	st = 0;
845 	s = g2->to.sym;
846 	while(s != S) {
847 		st = s->sym;
848 		if(st < 0 || st >= NSYM)
849 			st = 0;
850 		t = g2->to.type;
851 		if(t == D_ADDR)
852 			t = g2->to.index;
853 		if(h[st].type == t)
854 		if(h[st].sym == s)
855 			break;
856 		zname(s->name, t, sym);
857 		s->sym = sym;
858 		h[sym].sym = s;
859 		h[sym].type = t;
860 		st = sym;
861 		sym++;
862 		if(sym >= NSYM)
863 			sym = 1;
864 		if(st == sf)
865 			goto jackpot;
866 		break;
867 	}
868 	Bputc(&obuf, a);
869 	Bputc(&obuf, a>>8);
870 	Bputc(&obuf, lineno);
871 	Bputc(&obuf, lineno>>8);
872 	Bputc(&obuf, lineno>>16);
873 	Bputc(&obuf, lineno>>24);
874 	zaddr(&g2->from, sf);
875 	zaddr(&g2->to, st);
876 
877 out:
878 	if(a != AGLOBL && a != ADATA)
879 		pc++;
880 }
881 
882 void
883 outhist(void)
884 {
885 	Gen g;
886 	Hist *h;
887 	char *p, *q, *op, c;
888 	int n;
889 
890 	g = nullgen;
891 	c = pathchar();
892 	for(h = hist; h != H; h = h->link) {
893 		p = h->name;
894 		op = 0;
895 		/* on windows skip drive specifier in pathname */
896 		if(systemtype(Windows) && p && p[1] == ':'){
897 			p += 2;
898 			c = *p;
899 		}
900 		if(p && p[0] != c && h->offset == 0 && pathname){
901 			/* on windows skip drive specifier in pathname */
902 			if(systemtype(Windows) && pathname[1] == ':') {
903 				op = p;
904 				p = pathname+2;
905 				c = *p;
906 			} else if(pathname[0] == c){
907 				op = p;
908 				p = pathname;
909 			}
910 		}
911 		while(p) {
912 			q = strchr(p, c);
913 			if(q) {
914 				n = q-p;
915 				if(n == 0){
916 					n = 1;	/* leading "/" */
917 					*p = '/';	/* don't emit "\" on windows */
918 				}
919 				q++;
920 			} else {
921 				n = strlen(p);
922 				q = 0;
923 			}
924 			if(n) {
925 				Bputc(&obuf, ANAME);
926 				Bputc(&obuf, ANAME>>8);
927 				Bputc(&obuf, D_FILE);	/* type */
928 				Bputc(&obuf, 1);	/* sym */
929 				Bputc(&obuf, '<');
930 				Bwrite(&obuf, p, n);
931 				Bputc(&obuf, 0);
932 			}
933 			p = q;
934 			if(p == 0 && op) {
935 				p = op;
936 				op = 0;
937 			}
938 		}
939 		g.offset = h->offset;
940 
941 		Bputc(&obuf, AHISTORY);
942 		Bputc(&obuf, AHISTORY>>8);
943 		Bputc(&obuf, h->line);
944 		Bputc(&obuf, h->line>>8);
945 		Bputc(&obuf, h->line>>16);
946 		Bputc(&obuf, h->line>>24);
947 		zaddr(&nullgen, 0);
948 		zaddr(&g, 0);
949 	}
950 }
951 
952 #include "../cc/lexbody"
953 #include "../cc/macbody"
954