]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5a/lex.c
ndb/dns: lookup *all* entries in dblookup(), v4 and v6 queries in parallel, remove...
[plan9front.git] / sys / src / cmd / 5a / lex.c
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 = '5';
13         thestring = "arm";
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         case 't':
40                 thechar = 't';
41                 thestring = "thumb";
42                 break;
43         } ARGEND
44         if(*argv == 0) {
45                 print("usage: %ca [-options] file.s\n", thechar);
46                 errorexit();
47         }
48         if(argc > 1 && systemtype(Windows)){
49                 print("can't assemble multiple files on windows\n");
50                 errorexit();
51         }
52         if(argc > 1 && !systemtype(Windows)) {
53                 nproc = 1;
54                 if(p = getenv("NPROC"))
55                         nproc = atol(p);        /* */
56                 c = 0;
57                 nout = 0;
58                 for(;;) {
59                         while(nout < nproc && argc > 0) {
60                                 i = myfork();
61                                 if(i < 0) {
62                                         i = mywait(&status);
63                                         if(i < 0)
64                                                 errorexit();
65                                         if(status)
66                                                 c++;
67                                         nout--;
68                                         continue;
69                                 }
70                                 if(i == 0) {
71                                         print("%s:\n", *argv);
72                                         if(assemble(*argv))
73                                                 errorexit();
74                                         exits(0);
75                                 }
76                                 nout++;
77                                 argc--;
78                                 argv++;
79                         }
80                         i = mywait(&status);
81                         if(i < 0) {
82                                 if(c)
83                                         errorexit();
84                                 exits(0);
85                         }
86                         if(status)
87                                 c++;
88                         nout--;
89                 }
90         }
91         if(assemble(argv[0]))
92                 errorexit();
93         exits(0);
94 }
95
96 int
97 assemble(char *file)
98 {
99         char ofile[100], incfile[20], *p;
100         int i, of;
101
102         strcpy(ofile, file);
103         p = utfrrune(ofile, pathchar());
104         if(p) {
105                 include[0] = ofile;
106                 *p++ = 0;
107         } else
108                 p = ofile;
109         if(outfile == 0) {
110                 outfile = p;
111                 if(outfile){
112                         p = utfrrune(outfile, '.');
113                         if(p)
114                                 if(p[1] == 's' && p[2] == 0)
115                                         p[0] = 0;
116                         p = utfrune(outfile, 0);
117                         p[0] = '.';
118                         p[1] = thechar;
119                         p[2] = 0;
120                 } else
121                         outfile = "/dev/null";
122         }
123         p = getenv("INCLUDE");
124         if(p) {
125                 setinclude(p);
126         } else {
127                 if(systemtype(Plan9)) {
128                         sprint(incfile,"/%s/include", thestring);
129                         setinclude(strdup(incfile));
130                 }
131         }
132
133         of = mycreat(outfile, 0664);
134         if(of < 0) {
135                 yyerror("%ca: cannot create %s", thechar, outfile);
136                 errorexit();
137         }
138         Binit(&obuf, of, OWRITE);
139
140         pass = 1;
141         pinit(file);
142         for(i=0; i<nDlist; i++)
143                 dodefine(Dlist[i]);
144         yyparse();
145         if(nerrors) {
146                 cclean();
147                 return nerrors;
148         }
149
150         pass = 2;
151         outhist();
152         pinit(file);
153         for(i=0; i<nDlist; i++)
154                 dodefine(Dlist[i]);
155         yyparse();
156         cclean();
157         return nerrors;
158 }
159
160 struct
161 {
162         char    *name;
163         ushort  type;
164         ushort  value;
165 } itab[] =
166 {
167         "SP",           LSP,    D_AUTO,
168         "SB",           LSB,    D_EXTERN,
169         "FP",           LFP,    D_PARAM,
170         "PC",           LPC,    D_BRANCH,
171
172         "R",            LR,     0,
173         "R0",           LREG,   0,
174         "R1",           LREG,   1,
175         "R2",           LREG,   2,
176         "R3",           LREG,   3,
177         "R4",           LREG,   4,
178         "R5",           LREG,   5,
179         "R6",           LREG,   6,
180         "R7",           LREG,   7,
181         "R8",           LREG,   8,
182         "R9",           LREG,   9,
183         "R10",          LREG,   10,
184         "R11",          LREG,   11,
185         "R12",          LREG,   12,
186         "R13",          LREG,   13,
187         "R14",          LREG,   14,
188         "R15",          LREG,   15,
189
190         "F",            LF,     0,
191
192         "F0",           LFREG,  0,
193         "F1",           LFREG,  1,
194         "F2",           LFREG,  2,
195         "F3",           LFREG,  3,
196         "F4",           LFREG,  4,
197         "F5",           LFREG,  5,
198         "F6",           LFREG,  6,
199         "F7",           LFREG,  7,
200         "F8",           LFREG,  8,
201         "F9",           LFREG,  9,
202         "F10",          LFREG,  10,
203         "F11",          LFREG,  11,
204         "F12",          LFREG,  12,
205         "F13",          LFREG,  13,
206         "F14",          LFREG,  14,
207         "F15",          LFREG,  15,
208
209         "C",            LC,     0,
210
211         "C0",           LCREG,  0,
212         "C1",           LCREG,  1,
213         "C2",           LCREG,  2,
214         "C3",           LCREG,  3,
215         "C4",           LCREG,  4,
216         "C5",           LCREG,  5,
217         "C6",           LCREG,  6,
218         "C7",           LCREG,  7,
219         "C8",           LCREG,  8,
220         "C9",           LCREG,  9,
221         "C10",          LCREG,  10,
222         "C11",          LCREG,  11,
223         "C12",          LCREG,  12,
224         "C13",          LCREG,  13,
225         "C14",          LCREG,  14,
226         "C15",          LCREG,  15,
227
228         "CPSR",         LPSR,   0,
229         "SPSR",         LPSR,   1,
230
231         "FPSR",         LFCR,   0,
232         "FPCR",         LFCR,   1,
233
234         ".EQ",          LCOND,  0,
235         ".NE",          LCOND,  1,
236         ".CS",          LCOND,  2,
237         ".HS",          LCOND,  2,
238         ".CC",          LCOND,  3,
239         ".LO",          LCOND,  3,
240         ".MI",          LCOND,  4,
241         ".PL",          LCOND,  5,
242         ".VS",          LCOND,  6,
243         ".VC",          LCOND,  7,
244         ".HI",          LCOND,  8,
245         ".LS",          LCOND,  9,
246         ".GE",          LCOND,  10,
247         ".LT",          LCOND,  11,
248         ".GT",          LCOND,  12,
249         ".LE",          LCOND,  13,
250         ".AL",          LCOND,  Always,
251
252         ".U",           LS,     C_UBIT,
253         ".S",           LS,     C_SBIT,
254         ".W",           LS,     C_WBIT,
255         ".P",           LS,     C_PBIT,
256         ".PW",          LS,     C_WBIT|C_PBIT,
257         ".WP",          LS,     C_WBIT|C_PBIT,
258
259         ".F",           LS,     C_FBIT,
260
261         ".IBW",         LS,     C_WBIT|C_PBIT|C_UBIT,
262         ".IAW",         LS,     C_WBIT|C_UBIT,
263         ".DBW",         LS,     C_WBIT|C_PBIT,
264         ".DAW",         LS,     C_WBIT,
265         ".IB",          LS,     C_PBIT|C_UBIT,
266         ".IA",          LS,     C_UBIT,
267         ".DB",          LS,     C_PBIT,
268         ".DA",          LS,     0,
269
270         "@",            LAT,    0,
271
272         "AND",          LTYPE1, AAND,
273         "EOR",          LTYPE1, AEOR,
274         "SUB",          LTYPE1, ASUB,
275         "RSB",          LTYPE1, ARSB,
276         "ADD",          LTYPE1, AADD,
277         "ADC",          LTYPE1, AADC,
278         "SBC",          LTYPE1, ASBC,
279         "RSC",          LTYPE1, ARSC,
280         "ORR",          LTYPE1, AORR,
281         "BIC",          LTYPE1, ABIC,
282
283         "SLL",          LTYPE1, ASLL,
284         "SRL",          LTYPE1, ASRL,
285         "SRA",          LTYPE1, ASRA,
286         "ROR",          LTYPE1, AROR,
287
288         "MUL",          LTYPE1, AMUL,
289         "MULA",         LTYPEN, AMULA,
290         "DIV",          LTYPE1, ADIV,
291         "MOD",          LTYPE1, AMOD,
292
293         "MULL",         LTYPEM, AMULL,
294         "MULAL",        LTYPEM, AMULAL,
295         "MULLU",        LTYPEM, AMULLU,
296         "MULALU",       LTYPEM, AMULALU,
297
298         "MVN",          LTYPE2, AMVN,   /* op2 ignored */
299
300         "MOVB",         LTYPE3, AMOVB,
301         "MOVBU",        LTYPE3, AMOVBU,
302         "MOVH",         LTYPE3, AMOVH,
303         "MOVHU",        LTYPE3, AMOVHU,
304         "MOVW",         LTYPE3, AMOVW,
305
306         "MOVD",         LTYPE3, AMOVD,
307         "MOVDF",                LTYPE3, AMOVDF,
308         "MOVDW",        LTYPE3, AMOVDW,
309         "MOVF",         LTYPE3, AMOVF,
310         "MOVFD",                LTYPE3, AMOVFD,
311         "MOVFW",                LTYPE3, AMOVFW,
312         "MOVWD",        LTYPE3, AMOVWD,
313         "MOVWF",                LTYPE3, AMOVWF,
314
315         "LDREX",                LTYPE3, ALDREX,
316         "LDREXD",               LTYPE3, ALDREXD,
317         "STREX",                LTYPE9, ASTREX,
318         "STREXD",               LTYPE9, ASTREXD,
319
320 /*
321         "ABSF",         LTYPEI, AABSF,
322         "ABSD",         LTYPEI, AABSD,
323         "NEGF",         LTYPEI, ANEGF,
324         "NEGD",         LTYPEI, ANEGD,
325         "SQTF",         LTYPEI, ASQTF,
326         "SQTD",         LTYPEI, ASQTD,
327         "RNDF",         LTYPEI, ARNDF,
328         "RNDD",         LTYPEI, ARNDD,
329         "URDF",         LTYPEI, AURDF,
330         "URDD",         LTYPEI, AURDD,
331         "NRMF",         LTYPEI, ANRMF,
332         "NRMD",         LTYPEI, ANRMD,
333 */
334
335         "SQRTF",        LTYPEI, ASQRTF,
336         "SQRTD",        LTYPEI, ASQRTD,
337         "CMPF",         LTYPEL, ACMPF,
338         "CMPD",         LTYPEL, ACMPD,
339         "ADDF",         LTYPEK, AADDF,
340         "ADDD",         LTYPEK, AADDD,
341         "SUBF",         LTYPEK, ASUBF,
342         "SUBD",         LTYPEK, ASUBD,
343         "MULF",         LTYPEK, AMULF,
344         "MULD",         LTYPEK, AMULD,
345         "DIVF",         LTYPEK, ADIVF,
346         "DIVD",         LTYPEK, ADIVD,
347
348         "B",            LTYPE4, AB,
349         "BL",           LTYPE4, ABL,
350         "BX",           LTYPEBX,        ABX,
351
352         "BEQ",          LTYPE5, ABEQ,
353         "BNE",          LTYPE5, ABNE,
354         "BCS",          LTYPE5, ABCS,
355         "BHS",          LTYPE5, ABHS,
356         "BCC",          LTYPE5, ABCC,
357         "BLO",          LTYPE5, ABLO,
358         "BMI",          LTYPE5, ABMI,
359         "BPL",          LTYPE5, ABPL,
360         "BVS",          LTYPE5, ABVS,
361         "BVC",          LTYPE5, ABVC,
362         "BHI",          LTYPE5, ABHI,
363         "BLS",          LTYPE5, ABLS,
364         "BGE",          LTYPE5, ABGE,
365         "BLT",          LTYPE5, ABLT,
366         "BGT",          LTYPE5, ABGT,
367         "BLE",          LTYPE5, ABLE,
368         "BCASE",        LTYPE5, ABCASE,
369
370         "SWI",          LTYPE6, ASWI,
371
372         "CMP",          LTYPE7, ACMP,
373         "TST",          LTYPE7, ATST,
374         "TEQ",          LTYPE7, ATEQ,
375         "CMN",          LTYPE7, ACMN,
376
377         "MOVM",         LTYPE8, AMOVM,
378
379         "SWPBU",        LTYPE9, ASWPBU,
380         "SWPW",         LTYPE9, ASWPW,
381
382         "RET",          LTYPEA, ARET,
383         "RFE",          LTYPEA, ARFE,
384         "CLREX",        LTYPEA, ACLREX,
385
386         "TEXT",         LTYPEB, ATEXT,
387         "GLOBL",        LTYPEB, AGLOBL,
388         "DATA",         LTYPEC, ADATA,
389         "CASE",         LTYPED, ACASE,
390         "END",          LTYPEE, AEND,
391         "WORD",         LTYPEH, AWORD,
392         "NOP",          LTYPEI, ANOP,
393
394         "MCR",          LTYPEJ, 0,
395         "MRC",          LTYPEJ, 1,
396         0
397 };
398
399 void
400 cinit(void)
401 {
402         Sym *s;
403         int i;
404
405         nullgen.sym = S;
406         nullgen.offset = 0;
407         nullgen.type = D_NONE;
408         nullgen.name = D_NONE;
409         nullgen.reg = NREG;
410         if(FPCHIP)
411                 nullgen.dval = 0;
412         for(i=0; i<sizeof(nullgen.sval); i++)
413                 nullgen.sval[i] = 0;
414
415         nerrors = 0;
416         iostack = I;
417         iofree = I;
418         peekc = IGN;
419         nhunk = 0;
420         for(i=0; i<NHASH; i++)
421                 hash[i] = S;
422         for(i=0; itab[i].name; i++) {
423                 s = slookup(itab[i].name);
424                 s->type = itab[i].type;
425                 s->value = itab[i].value;
426         }
427
428         pathname = allocn(pathname, 0, 100);
429         if(getwd(pathname, 99) == 0) {
430                 pathname = allocn(pathname, 100, 900);
431                 if(getwd(pathname, 999) == 0)
432                         strcpy(pathname, "/???");
433         }
434 }
435
436 void
437 syminit(Sym *s)
438 {
439
440         s->type = LNAME;
441         s->value = 0;
442 }
443
444 int
445 isreg(Gen *g)
446 {
447
448         USED(g);
449         return 1;
450 }
451
452 void
453 cclean(void)
454 {
455
456         outcode(AEND, Always, &nullgen, NREG, &nullgen);
457         Bflush(&obuf);
458 }
459
460 void
461 zname(char *n, int t, int s)
462 {
463
464         Bputc(&obuf, ANAME);
465         Bputc(&obuf, t);        /* type */
466         Bputc(&obuf, s);        /* sym */
467         while(*n) {
468                 Bputc(&obuf, *n);
469                 n++;
470         }
471         Bputc(&obuf, 0);
472 }
473
474 void
475 zaddr(Gen *a, int s)
476 {
477         long l;
478         int i;
479         char *n;
480         Ieee e;
481
482         Bputc(&obuf, a->type);
483         Bputc(&obuf, a->reg);
484         Bputc(&obuf, s);
485         Bputc(&obuf, a->name);
486         switch(a->type) {
487         default:
488                 print("unknown type %d\n", a->type);
489                 exits("arg");
490
491         case D_NONE:
492         case D_REG:
493         case D_FREG:
494         case D_PSR:
495         case D_FPCR:
496                 break;
497
498         case D_REGREG:
499                 Bputc(&obuf, a->offset);
500                 break;
501
502         case D_OREG:
503         case D_CONST:
504         case D_BRANCH:
505         case D_SHIFT:
506                 l = a->offset;
507                 Bputc(&obuf, l);
508                 Bputc(&obuf, l>>8);
509                 Bputc(&obuf, l>>16);
510                 Bputc(&obuf, l>>24);
511                 break;
512
513         case D_SCONST:
514                 n = a->sval;
515                 for(i=0; i<NSNAME; i++) {
516                         Bputc(&obuf, *n);
517                         n++;
518                 }
519                 break;
520
521         case D_FCONST:
522                 ieeedtod(&e, a->dval);
523                 Bputc(&obuf, e.l);
524                 Bputc(&obuf, e.l>>8);
525                 Bputc(&obuf, e.l>>16);
526                 Bputc(&obuf, e.l>>24);
527                 Bputc(&obuf, e.h);
528                 Bputc(&obuf, e.h>>8);
529                 Bputc(&obuf, e.h>>16);
530                 Bputc(&obuf, e.h>>24);
531                 break;
532         }
533 }
534
535 static int bcode[] =
536 {
537         ABEQ,
538         ABNE,
539         ABCS,
540         ABCC,
541         ABMI,
542         ABPL,
543         ABVS,
544         ABVC,
545         ABHI,
546         ABLS,
547         ABGE,
548         ABLT,
549         ABGT,
550         ABLE,
551         AB,
552         ANOP,
553 };
554
555 void
556 outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
557 {
558         int sf, st, t;
559         Sym *s;
560
561         /* hack to make B.NE etc. work: turn it into the corresponding conditional */
562         if(a == AB){
563                 a = bcode[scond&0xf];
564                 scond = (scond & ~0xf) | Always;
565         }
566
567         if(pass == 1)
568                 goto out;
569 jackpot:
570         sf = 0;
571         s = g1->sym;
572         while(s != S) {
573                 sf = s->sym;
574                 if(sf < 0 || sf >= NSYM)
575                         sf = 0;
576                 t = g1->name;
577                 if(h[sf].type == t)
578                 if(h[sf].sym == s)
579                         break;
580                 zname(s->name, t, sym);
581                 s->sym = sym;
582                 h[sym].sym = s;
583                 h[sym].type = t;
584                 sf = sym;
585                 sym++;
586                 if(sym >= NSYM)
587                         sym = 1;
588                 break;
589         }
590         st = 0;
591         s = g2->sym;
592         while(s != S) {
593                 st = s->sym;
594                 if(st < 0 || st >= NSYM)
595                         st = 0;
596                 t = g2->name;
597                 if(h[st].type == t)
598                 if(h[st].sym == s)
599                         break;
600                 zname(s->name, t, sym);
601                 s->sym = sym;
602                 h[sym].sym = s;
603                 h[sym].type = t;
604                 st = sym;
605                 sym++;
606                 if(sym >= NSYM)
607                         sym = 1;
608                 if(st == sf)
609                         goto jackpot;
610                 break;
611         }
612         Bputc(&obuf, a);
613         Bputc(&obuf, scond);
614         Bputc(&obuf, reg);
615         Bputc(&obuf, lineno);
616         Bputc(&obuf, lineno>>8);
617         Bputc(&obuf, lineno>>16);
618         Bputc(&obuf, lineno>>24);
619         zaddr(g1, sf);
620         zaddr(g2, st);
621
622 out:
623         if(a != AGLOBL && a != ADATA)
624                 pc++;
625 }
626
627 void
628 outhist(void)
629 {
630         Gen g;
631         Hist *h;
632         char *p, *q, *op, c;
633         int n;
634
635         g = nullgen;
636         c = pathchar();
637         for(h = hist; h != H; h = h->link) {
638                 p = h->name;
639                 op = 0;
640                 /* on windows skip drive specifier in pathname */
641                 if(systemtype(Windows) && p && p[1] == ':'){
642                         p += 2;
643                         c = *p;
644                 }
645                 if(p && p[0] != c && h->offset == 0 && pathname){
646                         /* on windows skip drive specifier in pathname */
647                         if(systemtype(Windows) && pathname[1] == ':') {
648                                 op = p;
649                                 p = pathname+2;
650                                 c = *p;
651                         } else if(pathname[0] == c){
652                                 op = p;
653                                 p = pathname;
654                         }
655                 }
656                 while(p) {
657                         q = strchr(p, c);
658                         if(q) {
659                                 n = q-p;
660                                 if(n == 0){
661                                         n = 1;  /* leading "/" */
662                                         *p = '/';       /* don't emit "\" on windows */
663                                 }
664                                 q++;
665                         } else {
666                                 n = strlen(p);
667                                 q = 0;
668                         }
669                         if(n) {
670                                 Bputc(&obuf, ANAME);
671                                 Bputc(&obuf, D_FILE);   /* type */
672                                 Bputc(&obuf, 1);        /* sym */
673                                 Bputc(&obuf, '<');
674                                 Bwrite(&obuf, p, n);
675                                 Bputc(&obuf, 0);
676                         }
677                         p = q;
678                         if(p == 0 && op) {
679                                 p = op;
680                                 op = 0;
681                         }
682                 }
683                 g.offset = h->offset;
684
685                 Bputc(&obuf, AHISTORY);
686                 Bputc(&obuf, Always);
687                 Bputc(&obuf, 0);
688                 Bputc(&obuf, h->line);
689                 Bputc(&obuf, h->line>>8);
690                 Bputc(&obuf, h->line>>16);
691                 Bputc(&obuf, h->line>>24);
692                 zaddr(&nullgen, 0);
693                 zaddr(&g, 0);
694         }
695 }
696
697 #include "../cc/lexbody"
698 #include "../cc/macbody"
699 #include "../cc/compat"