]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8a/lex.c
/rc/bin/9fs: add partition argument for 9fat
[plan9front.git] / sys / src / cmd / 8a / lex.c
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         "DAA",          LTYPE0, ADAA,
278         "DAS",          LTYPE0, ADAS,
279         "DATA",         LTYPED, ADATA,
280         "DECB",         LTYPE1, ADECB,
281         "DECL",         LTYPE1, ADECL,
282         "DECW",         LTYPE1, ADECW,
283         "DIVB",         LTYPE2, ADIVB,
284         "DIVL",         LTYPE2, ADIVL,
285         "DIVW",         LTYPE2, ADIVW,
286         "END",          LTYPE0, AEND,
287         "ENTER",        LTYPE2, AENTER,
288         "GLOBL",        LTYPET, AGLOBL,
289         "HLT",          LTYPE0, AHLT,
290         "IDIVB",        LTYPE2, AIDIVB,
291         "IDIVL",        LTYPE2, AIDIVL,
292         "IDIVW",        LTYPE2, AIDIVW,
293         "IMULB",        LTYPE2, AIMULB,
294         "IMULL",        LTYPE2, AIMULL,
295         "IMULW",        LTYPE2, AIMULW,
296         "INB",          LTYPE0, AINB,
297         "INL",          LTYPE0, AINL,
298         "INW",          LTYPE0, AINW,
299         "INCB",         LTYPE1, AINCB,
300         "INCL",         LTYPE1, AINCL,
301         "INCW",         LTYPE1, AINCW,
302         "INSB",         LTYPE0, AINSB,
303         "INSL",         LTYPE0, AINSL,
304         "INSW",         LTYPE0, AINSW,
305         "INT",          LTYPE2, AINT,
306         "INTO",         LTYPE0, AINTO,
307         "IRETL",        LTYPE0, AIRETL,
308         "IRETW",        LTYPE0, AIRETW,
309
310         "JOS",          LTYPER, AJOS,
311         "JO",           LTYPER, AJOS,   /* alternate */
312         "JOC",          LTYPER, AJOC,
313         "JNO",          LTYPER, AJOC,   /* alternate */
314         "JCS",          LTYPER, AJCS,
315         "JB",           LTYPER, AJCS,   /* alternate */
316         "JC",           LTYPER, AJCS,   /* alternate */
317         "JNAE",         LTYPER, AJCS,   /* alternate */
318         "JLO",          LTYPER, AJCS,   /* alternate */
319         "JCC",          LTYPER, AJCC,
320         "JAE",          LTYPER, AJCC,   /* alternate */
321         "JNB",          LTYPER, AJCC,   /* alternate */
322         "JNC",          LTYPER, AJCC,   /* alternate */
323         "JHS",          LTYPER, AJCC,   /* alternate */
324         "JEQ",          LTYPER, AJEQ,
325         "JE",           LTYPER, AJEQ,   /* alternate */
326         "JZ",           LTYPER, AJEQ,   /* alternate */
327         "JNE",          LTYPER, AJNE,
328         "JNZ",          LTYPER, AJNE,   /* alternate */
329         "JLS",          LTYPER, AJLS,
330         "JBE",          LTYPER, AJLS,   /* alternate */
331         "JNA",          LTYPER, AJLS,   /* alternate */
332         "JHI",          LTYPER, AJHI,
333         "JA",           LTYPER, AJHI,   /* alternate */
334         "JNBE",         LTYPER, AJHI,   /* alternate */
335         "JMI",          LTYPER, AJMI,
336         "JS",           LTYPER, AJMI,   /* alternate */
337         "JPL",          LTYPER, AJPL,
338         "JNS",          LTYPER, AJPL,   /* alternate */
339         "JPS",          LTYPER, AJPS,
340         "JP",           LTYPER, AJPS,   /* alternate */
341         "JPE",          LTYPER, AJPS,   /* alternate */
342         "JPC",          LTYPER, AJPC,
343         "JNP",          LTYPER, AJPC,   /* alternate */
344         "JPO",          LTYPER, AJPC,   /* alternate */
345         "JLT",          LTYPER, AJLT,
346         "JL",           LTYPER, AJLT,   /* alternate */
347         "JNGE",         LTYPER, AJLT,   /* alternate */
348         "JGE",          LTYPER, AJGE,
349         "JNL",          LTYPER, AJGE,   /* alternate */
350         "JLE",          LTYPER, AJLE,
351         "JNG",          LTYPER, AJLE,   /* alternate */
352         "JGT",          LTYPER, AJGT,
353         "JG",           LTYPER, AJGT,   /* alternate */
354         "JNLE",         LTYPER, AJGT,   /* alternate */
355
356         "JCXZ",         LTYPER, AJCXZ,
357         "JMP",          LTYPEC, AJMP,
358         "LAHF",         LTYPE0, ALAHF,
359         "LARL",         LTYPE3, ALARL,
360         "LARW",         LTYPE3, ALARW,
361         "LEAL",         LTYPE3, ALEAL,
362         "LEAW",         LTYPE3, ALEAW,
363         "LEAVEL",       LTYPE0, ALEAVEL,
364         "LEAVEW",       LTYPE0, ALEAVEW,
365         "LOCK",         LTYPE0, ALOCK,
366         "LODSB",        LTYPE0, ALODSB,
367         "LODSL",        LTYPE0, ALODSL,
368         "LODSW",        LTYPE0, ALODSW,
369         "LONG",         LTYPE2, ALONG,
370         "LOOP",         LTYPER, ALOOP,
371         "LOOPEQ",       LTYPER, ALOOPEQ,
372         "LOOPNE",       LTYPER, ALOOPNE,
373         "LSLL",         LTYPE3, ALSLL,
374         "LSLW",         LTYPE3, ALSLW,
375         "MOVB",         LTYPE3, AMOVB,
376         "MOVL",         LTYPEM, AMOVL,
377         "MOVW",         LTYPEM, AMOVW,
378         "MOVBLSX",      LTYPE3, AMOVBLSX,
379         "MOVBLZX",      LTYPE3, AMOVBLZX,
380         "MOVBWSX",      LTYPE3, AMOVBWSX,
381         "MOVBWZX",      LTYPE3, AMOVBWZX,
382         "MOVWLSX",      LTYPE3, AMOVWLSX,
383         "MOVWLZX",      LTYPE3, AMOVWLZX,
384         "MOVSB",        LTYPE0, AMOVSB,
385         "MOVSL",        LTYPE0, AMOVSL,
386         "MOVSW",        LTYPE0, AMOVSW,
387         "MULB",         LTYPE2, AMULB,
388         "MULL",         LTYPE2, AMULL,
389         "MULW",         LTYPE2, AMULW,
390         "NEGB",         LTYPE1, ANEGB,
391         "NEGL",         LTYPE1, ANEGL,
392         "NEGW",         LTYPE1, ANEGW,
393         "NOP",          LTYPEN, ANOP,
394         "NOTB",         LTYPE1, ANOTB,
395         "NOTL",         LTYPE1, ANOTL,
396         "NOTW",         LTYPE1, ANOTW,
397         "ORB",          LTYPE3, AORB,
398         "ORL",          LTYPE3, AORL,
399         "ORW",          LTYPE3, AORW,
400         "OUTB",         LTYPE0, AOUTB,
401         "OUTL",         LTYPE0, AOUTL,
402         "OUTW",         LTYPE0, AOUTW,
403         "OUTSB",        LTYPE0, AOUTSB,
404         "OUTSL",        LTYPE0, AOUTSL,
405         "OUTSW",        LTYPE0, AOUTSW,
406         "POPAL",        LTYPE0, APOPAL,
407         "POPAW",        LTYPE0, APOPAW,
408         "POPFL",        LTYPE0, APOPFL,
409         "POPFW",        LTYPE0, APOPFW,
410         "POPL",         LTYPE1, APOPL,
411         "POPW",         LTYPE1, APOPW,
412         "PUSHAL",       LTYPE0, APUSHAL,
413         "PUSHAW",       LTYPE0, APUSHAW,
414         "PUSHFL",       LTYPE0, APUSHFL,
415         "PUSHFW",       LTYPE0, APUSHFW,
416         "PUSHL",        LTYPE2, APUSHL,
417         "PUSHW",        LTYPE2, APUSHW,
418         "RCLB",         LTYPE3, ARCLB,
419         "RCLL",         LTYPE3, ARCLL,
420         "RCLW",         LTYPE3, ARCLW,
421         "RCRB",         LTYPE3, ARCRB,
422         "RCRL",         LTYPE3, ARCRL,
423         "RCRW",         LTYPE3, ARCRW,
424         "REP",          LTYPE0, AREP,
425         "REPN",         LTYPE0, AREPN,
426         "RET",          LTYPE0, ARET,
427         "ROLB",         LTYPE3, AROLB,
428         "ROLL",         LTYPE3, AROLL,
429         "ROLW",         LTYPE3, AROLW,
430         "RORB",         LTYPE3, ARORB,
431         "RORL",         LTYPE3, ARORL,
432         "RORW",         LTYPE3, ARORW,
433         "SAHF",         LTYPE0, ASAHF,
434         "SALB",         LTYPE3, ASALB,
435         "SALL",         LTYPE3, ASALL,
436         "SALW",         LTYPE3, ASALW,
437         "SARB",         LTYPE3, ASARB,
438         "SARL",         LTYPE3, ASARL,
439         "SARW",         LTYPE3, ASARW,
440         "SBBB",         LTYPE3, ASBBB,
441         "SBBL",         LTYPE3, ASBBL,
442         "SBBW",         LTYPE3, ASBBW,
443         "SCASB",        LTYPE0, ASCASB,
444         "SCASL",        LTYPE0, ASCASL,
445         "SCASW",        LTYPE0, ASCASW,
446         "SETCC",        LTYPE1, ASETCC,
447         "SETCS",        LTYPE1, ASETCS,
448         "SETEQ",        LTYPE1, ASETEQ,
449         "SETGE",        LTYPE1, ASETGE,
450         "SETGT",        LTYPE1, ASETGT,
451         "SETHI",        LTYPE1, ASETHI,
452         "SETLE",        LTYPE1, ASETLE,
453         "SETLS",        LTYPE1, ASETLS,
454         "SETLT",        LTYPE1, ASETLT,
455         "SETMI",        LTYPE1, ASETMI,
456         "SETNE",        LTYPE1, ASETNE,
457         "SETOC",        LTYPE1, ASETOC,
458         "SETOS",        LTYPE1, ASETOS,
459         "SETPC",        LTYPE1, ASETPC,
460         "SETPL",        LTYPE1, ASETPL,
461         "SETPS",        LTYPE1, ASETPS,
462         "CDQ",          LTYPE0, ACDQ,
463         "CWD",          LTYPE0, ACWD,
464         "SHLB",         LTYPE3, ASHLB,
465         "SHLL",         LTYPES, ASHLL,
466         "SHLW",         LTYPES, ASHLW,
467         "SHRB",         LTYPE3, ASHRB,
468         "SHRL",         LTYPES, ASHRL,
469         "SHRW",         LTYPES, ASHRW,
470         "STC",          LTYPE0, ASTC,
471         "STD",          LTYPE0, ASTD,
472         "STI",          LTYPE0, ASTI,
473         "STOSB",        LTYPE0, ASTOSB,
474         "STOSL",        LTYPE0, ASTOSL,
475         "STOSW",        LTYPE0, ASTOSW,
476         "SUBB",         LTYPE3, ASUBB,
477         "SUBL",         LTYPE3, ASUBL,
478         "SUBW",         LTYPE3, ASUBW,
479         "SYSCALL",      LTYPE0, ASYSCALL,
480         "TESTB",        LTYPE3, ATESTB,
481         "TESTL",        LTYPE3, ATESTL,
482         "TESTW",        LTYPE3, ATESTW,
483         "TEXT",         LTYPET, ATEXT,
484         "VERR",         LTYPE2, AVERR,
485         "VERW",         LTYPE2, AVERW,
486         "WAIT",         LTYPE0, AWAIT,
487         "WORD",         LTYPE2, AWORD,
488         "XCHGB",        LTYPE3, AXCHGB,
489         "XCHGL",        LTYPE3, AXCHGL,
490         "XCHGW",        LTYPE3, AXCHGW,
491         "XLAT",         LTYPE2, AXLAT,
492         "XORB",         LTYPE3, AXORB,
493         "XORL",         LTYPE3, AXORL,
494         "XORW",         LTYPE3, AXORW,
495
496         "FMOVB",        LTYPE3, AFMOVB,
497         "FMOVBP",       LTYPE3, AFMOVBP,
498         "FMOVD",        LTYPE3, AFMOVD,
499         "FMOVDP",       LTYPE3, AFMOVDP,
500         "FMOVF",        LTYPE3, AFMOVF,
501         "FMOVFP",       LTYPE3, AFMOVFP,
502         "FMOVL",        LTYPE3, AFMOVL,
503         "FMOVLP",       LTYPE3, AFMOVLP,
504         "FMOVV",        LTYPE3, AFMOVV,
505         "FMOVVP",       LTYPE3, AFMOVVP,
506         "FMOVW",        LTYPE3, AFMOVW,
507         "FMOVWP",       LTYPE3, AFMOVWP,
508         "FMOVX",        LTYPE3, AFMOVX,
509         "FMOVXP",       LTYPE3, AFMOVXP,
510         "FCOMB",        LTYPE3, AFCOMB,
511         "FCOMBP",       LTYPE3, AFCOMBP,
512         "FCOMD",        LTYPE3, AFCOMD,
513         "FCOMDP",       LTYPE3, AFCOMDP,
514         "FCOMDPP",      LTYPE3, AFCOMDPP,
515         "FCOMF",        LTYPE3, AFCOMF,
516         "FCOMFP",       LTYPE3, AFCOMFP,
517         "FCOML",        LTYPE3, AFCOML,
518         "FCOMLP",       LTYPE3, AFCOMLP,
519         "FCOMW",        LTYPE3, AFCOMW,
520         "FCOMWP",       LTYPE3, AFCOMWP,
521         "FUCOM",        LTYPE3, AFUCOM,
522         "FUCOMP",       LTYPE3, AFUCOMP,
523         "FUCOMPP",      LTYPE3, AFUCOMPP,
524         "FADDW",        LTYPE3, AFADDW,
525         "FADDL",        LTYPE3, AFADDL,
526         "FADDF",        LTYPE3, AFADDF,
527         "FADDD",        LTYPE3, AFADDD,
528         "FADDDP",       LTYPE3, AFADDDP,
529         "FSUBDP",       LTYPE3, AFSUBDP,
530         "FSUBW",        LTYPE3, AFSUBW,
531         "FSUBL",        LTYPE3, AFSUBL,
532         "FSUBF",        LTYPE3, AFSUBF,
533         "FSUBD",        LTYPE3, AFSUBD,
534         "FSUBRDP",      LTYPE3, AFSUBRDP,
535         "FSUBRW",       LTYPE3, AFSUBRW,
536         "FSUBRL",       LTYPE3, AFSUBRL,
537         "FSUBRF",       LTYPE3, AFSUBRF,
538         "FSUBRD",       LTYPE3, AFSUBRD,
539         "FMULDP",       LTYPE3, AFMULDP,
540         "FMULW",        LTYPE3, AFMULW,
541         "FMULL",        LTYPE3, AFMULL,
542         "FMULF",        LTYPE3, AFMULF,
543         "FMULD",        LTYPE3, AFMULD,
544         "FDIVDP",       LTYPE3, AFDIVDP,
545         "FDIVW",        LTYPE3, AFDIVW,
546         "FDIVL",        LTYPE3, AFDIVL,
547         "FDIVF",        LTYPE3, AFDIVF,
548         "FDIVD",        LTYPE3, AFDIVD,
549         "FDIVRDP",      LTYPE3, AFDIVRDP,
550         "FDIVRW",       LTYPE3, AFDIVRW,
551         "FDIVRL",       LTYPE3, AFDIVRL,
552         "FDIVRF",       LTYPE3, AFDIVRF,
553         "FDIVRD",       LTYPE3, AFDIVRD,
554         "FXCHD",        LTYPE3, AFXCHD,
555         "FFREE",        LTYPE1, AFFREE,
556         "FLDCW",        LTYPE2, AFLDCW,
557         "FLDENV",       LTYPE1, AFLDENV,
558         "FRSTOR",       LTYPE2, AFRSTOR,
559         "FSAVE",        LTYPE1, AFSAVE,
560         "FSTCW",        LTYPE1, AFSTCW,
561         "FSTENV",       LTYPE1, AFSTENV,
562         "FSTSW",        LTYPE1, AFSTSW,
563         "F2XM1",        LTYPE0, AF2XM1,
564         "FABS",         LTYPE0, AFABS,
565         "FCHS",         LTYPE0, AFCHS,
566         "FCLEX",        LTYPE0, AFCLEX,
567         "FCOS",         LTYPE0, AFCOS,
568         "FDECSTP",      LTYPE0, AFDECSTP,
569         "FINCSTP",      LTYPE0, AFINCSTP,
570         "FINIT",        LTYPE0, AFINIT,
571         "FLD1",         LTYPE0, AFLD1,
572         "FLDL2E",       LTYPE0, AFLDL2E,
573         "FLDL2T",       LTYPE0, AFLDL2T,
574         "FLDLG2",       LTYPE0, AFLDLG2,
575         "FLDLN2",       LTYPE0, AFLDLN2,
576         "FLDPI",        LTYPE0, AFLDPI,
577         "FLDZ",         LTYPE0, AFLDZ,
578         "FNOP",         LTYPE0, AFNOP,
579         "FPATAN",       LTYPE0, AFPATAN,
580         "FPREM",        LTYPE0, AFPREM,
581         "FPREM1",       LTYPE0, AFPREM1,
582         "FPTAN",        LTYPE0, AFPTAN,
583         "FRNDINT",      LTYPE0, AFRNDINT,
584         "FSCALE",       LTYPE0, AFSCALE,
585         "FSIN",         LTYPE0, AFSIN,
586         "FSINCOS",      LTYPE0, AFSINCOS,
587         "FSQRT",        LTYPE0, AFSQRT,
588         "FTST",         LTYPE0, AFTST,
589         "FXAM",         LTYPE0, AFXAM,
590         "FXTRACT",      LTYPE0, AFXTRACT,
591         "FYL2X",        LTYPE0, AFYL2X,
592         "FYL2XP1",      LTYPE0, AFYL2XP1,
593
594         0
595 };
596
597 void
598 cinit(void)
599 {
600         Sym *s;
601         int i;
602
603         nullgen.sym = S;
604         nullgen.offset = 0;
605         if(FPCHIP)
606                 nullgen.dval = 0;
607         for(i=0; i<sizeof(nullgen.sval); i++)
608                 nullgen.sval[i] = 0;
609         nullgen.type = D_NONE;
610         nullgen.index = D_NONE;
611         nullgen.scale = 0;
612
613         nerrors = 0;
614         iostack = I;
615         iofree = I;
616         peekc = IGN;
617         nhunk = 0;
618         for(i=0; i<NHASH; i++)
619                 hash[i] = S;
620         for(i=0; itab[i].name; i++) {
621                 s = slookup(itab[i].name);
622                 if(s->type != LNAME)
623                         yyerror("double initialization %s", itab[i].name);
624                 s->type = itab[i].type;
625                 s->value = itab[i].value;
626         }
627
628         pathname = allocn(pathname, 0, 100);
629         if(mygetwd(pathname, 99) == 0) {
630                 pathname = allocn(pathname, 100, 900);
631                 if(mygetwd(pathname, 999) == 0)
632                         strcpy(pathname, "/???");
633         }
634 }
635
636 void
637 checkscale(int scale)
638 {
639
640         switch(scale) {
641         case 1:
642         case 2:
643         case 4:
644         case 8:
645                 return;
646         }
647         yyerror("scale must be 1248: %d", scale);
648 }
649
650 void
651 syminit(Sym *s)
652 {
653
654         s->type = LNAME;
655         s->value = 0;
656 }
657
658 void
659 cclean(void)
660 {
661         Gen2 g2;
662
663         g2.from = nullgen;
664         g2.to = nullgen;
665         outcode(AEND, &g2);
666         Bflush(&obuf);
667 }
668
669 void
670 zname(char *n, int t, int s)
671 {
672
673         Bputc(&obuf, ANAME);            /* as(2) */
674         Bputc(&obuf, ANAME>>8);
675         Bputc(&obuf, t);                /* type */
676         Bputc(&obuf, s);                /* sym */
677         while(*n) {
678                 Bputc(&obuf, *n);
679                 n++;
680         }
681         Bputc(&obuf, 0);
682 }
683
684 void
685 zaddr(Gen *a, int s)
686 {
687         long l;
688         int i, t;
689         char *n;
690         Ieee e;
691
692         t = 0;
693         if(a->index != D_NONE || a->scale != 0)
694                 t |= T_INDEX;
695         if(a->offset != 0)
696                 t |= T_OFFSET;
697         if(s != 0)
698                 t |= T_SYM;
699
700         switch(a->type) {
701         default:
702                 t |= T_TYPE;
703                 break;
704         case D_FCONST:
705                 t |= T_FCONST;
706                 break;
707         case D_SCONST:
708                 t |= T_SCONST;
709                 break;
710         case D_NONE:
711                 break;
712         }
713         Bputc(&obuf, t);
714
715         if(t & T_INDEX) {       /* implies index, scale */
716                 Bputc(&obuf, a->index);
717                 Bputc(&obuf, a->scale);
718         }
719         if(t & T_OFFSET) {      /* implies offset */
720                 l = a->offset;
721                 Bputc(&obuf, l);
722                 Bputc(&obuf, l>>8);
723                 Bputc(&obuf, l>>16);
724                 Bputc(&obuf, l>>24);
725         }
726         if(t & T_SYM)           /* implies sym */
727                 Bputc(&obuf, s);
728         if(t & T_FCONST) {
729                 ieeedtod(&e, a->dval);
730                 l = e.l;
731                 Bputc(&obuf, l);
732                 Bputc(&obuf, l>>8);
733                 Bputc(&obuf, l>>16);
734                 Bputc(&obuf, l>>24);
735                 l = e.h;
736                 Bputc(&obuf, l);
737                 Bputc(&obuf, l>>8);
738                 Bputc(&obuf, l>>16);
739                 Bputc(&obuf, l>>24);
740                 return;
741         }
742         if(t & T_SCONST) {
743                 n = a->sval;
744                 for(i=0; i<NSNAME; i++) {
745                         Bputc(&obuf, *n);
746                         n++;
747                 }
748                 return;
749         }
750         if(t & T_TYPE)
751                 Bputc(&obuf, a->type);
752 }
753
754 void
755 outcode(int a, Gen2 *g2)
756 {
757         int sf, st, t;
758         Sym *s;
759
760         if(pass == 1)
761                 goto out;
762
763 jackpot:
764         sf = 0;
765         s = g2->from.sym;
766         while(s != S) {
767                 sf = s->sym;
768                 if(sf < 0 || sf >= NSYM)
769                         sf = 0;
770                 t = g2->from.type;
771                 if(t == D_ADDR)
772                         t = g2->from.index;
773                 if(h[sf].type == t)
774                 if(h[sf].sym == s)
775                         break;
776                 zname(s->name, t, sym);
777                 s->sym = sym;
778                 h[sym].sym = s;
779                 h[sym].type = t;
780                 sf = sym;
781                 sym++;
782                 if(sym >= NSYM)
783                         sym = 1;
784                 break;
785         }
786         st = 0;
787         s = g2->to.sym;
788         while(s != S) {
789                 st = s->sym;
790                 if(st < 0 || st >= NSYM)
791                         st = 0;
792                 t = g2->to.type;
793                 if(t == D_ADDR)
794                         t = g2->to.index;
795                 if(h[st].type == t)
796                 if(h[st].sym == s)
797                         break;
798                 zname(s->name, t, sym);
799                 s->sym = sym;
800                 h[sym].sym = s;
801                 h[sym].type = t;
802                 st = sym;
803                 sym++;
804                 if(sym >= NSYM)
805                         sym = 1;
806                 if(st == sf)
807                         goto jackpot;
808                 break;
809         }
810         Bputc(&obuf, a);
811         Bputc(&obuf, a>>8);
812         Bputc(&obuf, lineno);
813         Bputc(&obuf, lineno>>8);
814         Bputc(&obuf, lineno>>16);
815         Bputc(&obuf, lineno>>24);
816         zaddr(&g2->from, sf);
817         zaddr(&g2->to, st);
818
819 out:
820         if(a != AGLOBL && a != ADATA)
821                 pc++;
822 }
823
824 void
825 outhist(void)
826 {
827         Gen g;
828         Hist *h;
829         char *p, *q, *op, c;
830         int n;
831
832         g = nullgen;
833         c = pathchar();
834         for(h = hist; h != H; h = h->link) {
835                 p = h->name;
836                 op = 0;
837                 /* on windows skip drive specifier in pathname */
838                 if(systemtype(Windows) && p && p[1] == ':'){
839                         p += 2;
840                         c = *p;
841                 }
842                 if(p && p[0] != c && h->offset == 0 && pathname){
843                         /* on windows skip drive specifier in pathname */
844                         if(systemtype(Windows) && pathname[1] == ':') {
845                                 op = p;
846                                 p = pathname+2;
847                                 c = *p;
848                         } else if(pathname[0] == c){
849                                 op = p;
850                                 p = pathname;
851                         }
852                 }
853                 while(p) {
854                         q = strchr(p, c);
855                         if(q) {
856                                 n = q-p;
857                                 if(n == 0){
858                                         n = 1;  /* leading "/" */
859                                         *p = '/';       /* don't emit "\" on windows */
860                                 }
861                                 q++;
862                         } else {
863                                 n = strlen(p);
864                                 q = 0;
865                         }
866                         if(n) {
867                                 Bputc(&obuf, ANAME);
868                                 Bputc(&obuf, ANAME>>8);
869                                 Bputc(&obuf, D_FILE);   /* type */
870                                 Bputc(&obuf, 1);        /* sym */
871                                 Bputc(&obuf, '<');
872                                 Bwrite(&obuf, p, n);
873                                 Bputc(&obuf, 0);
874                         }
875                         p = q;
876                         if(p == 0 && op) {
877                                 p = op;
878                                 op = 0;
879                         }
880                 }
881                 g.offset = h->offset;
882
883                 Bputc(&obuf, AHISTORY);
884                 Bputc(&obuf, AHISTORY>>8);
885                 Bputc(&obuf, h->line);
886                 Bputc(&obuf, h->line>>8);
887                 Bputc(&obuf, h->line>>16);
888                 Bputc(&obuf, h->line>>24);
889                 zaddr(&nullgen, 0);
890                 zaddr(&g, 0);
891         }
892 }
893
894 #include "../cc/lexbody"
895 #include "../cc/macbody"
896 #include "../cc/compat"