]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5a/lex.c
/rc/bin/9fs: add partition argument for 9fat
[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
287         "MUL",          LTYPE1, AMUL,
288         "MULA",         LTYPEN, AMULA,
289         "DIV",          LTYPE1, ADIV,
290         "MOD",          LTYPE1, AMOD,
291
292         "MULL",         LTYPEM, AMULL,
293         "MULAL",        LTYPEM, AMULAL,
294         "MULLU",        LTYPEM, AMULLU,
295         "MULALU",       LTYPEM, AMULALU,
296
297         "MVN",          LTYPE2, AMVN,   /* op2 ignored */
298
299         "MOVB",         LTYPE3, AMOVB,
300         "MOVBU",        LTYPE3, AMOVBU,
301         "MOVH",         LTYPE3, AMOVH,
302         "MOVHU",        LTYPE3, AMOVHU,
303         "MOVW",         LTYPE3, AMOVW,
304
305         "MOVD",         LTYPE3, AMOVD,
306         "MOVDF",                LTYPE3, AMOVDF,
307         "MOVDW",        LTYPE3, AMOVDW,
308         "MOVF",         LTYPE3, AMOVF,
309         "MOVFD",                LTYPE3, AMOVFD,
310         "MOVFW",                LTYPE3, AMOVFW,
311         "MOVWD",        LTYPE3, AMOVWD,
312         "MOVWF",                LTYPE3, AMOVWF,
313
314 /*
315         "ABSF",         LTYPEI, AABSF,
316         "ABSD",         LTYPEI, AABSD,
317         "NEGF",         LTYPEI, ANEGF,
318         "NEGD",         LTYPEI, ANEGD,
319         "SQTF",         LTYPEI, ASQTF,
320         "SQTD",         LTYPEI, ASQTD,
321         "RNDF",         LTYPEI, ARNDF,
322         "RNDD",         LTYPEI, ARNDD,
323         "URDF",         LTYPEI, AURDF,
324         "URDD",         LTYPEI, AURDD,
325         "NRMF",         LTYPEI, ANRMF,
326         "NRMD",         LTYPEI, ANRMD,
327 */
328
329         "CMPF",         LTYPEL, ACMPF,
330         "CMPD",         LTYPEL, ACMPD,
331         "ADDF",         LTYPEK, AADDF,
332         "ADDD",         LTYPEK, AADDD,
333         "SUBF",         LTYPEK, ASUBF,
334         "SUBD",         LTYPEK, ASUBD,
335         "MULF",         LTYPEK, AMULF,
336         "MULD",         LTYPEK, AMULD,
337         "DIVF",         LTYPEK, ADIVF,
338         "DIVD",         LTYPEK, ADIVD,
339
340         "B",            LTYPE4, AB,
341         "BL",           LTYPE4, ABL,
342         "BX",           LTYPEBX,        ABX,
343
344         "BEQ",          LTYPE5, ABEQ,
345         "BNE",          LTYPE5, ABNE,
346         "BCS",          LTYPE5, ABCS,
347         "BHS",          LTYPE5, ABHS,
348         "BCC",          LTYPE5, ABCC,
349         "BLO",          LTYPE5, ABLO,
350         "BMI",          LTYPE5, ABMI,
351         "BPL",          LTYPE5, ABPL,
352         "BVS",          LTYPE5, ABVS,
353         "BVC",          LTYPE5, ABVC,
354         "BHI",          LTYPE5, ABHI,
355         "BLS",          LTYPE5, ABLS,
356         "BGE",          LTYPE5, ABGE,
357         "BLT",          LTYPE5, ABLT,
358         "BGT",          LTYPE5, ABGT,
359         "BLE",          LTYPE5, ABLE,
360         "BCASE",        LTYPE5, ABCASE,
361
362         "SWI",          LTYPE6, ASWI,
363
364         "CMP",          LTYPE7, ACMP,
365         "TST",          LTYPE7, ATST,
366         "TEQ",          LTYPE7, ATEQ,
367         "CMN",          LTYPE7, ACMN,
368
369         "MOVM",         LTYPE8, AMOVM,
370
371         "SWPBU",        LTYPE9, ASWPBU,
372         "SWPW",         LTYPE9, ASWPW,
373
374         "RET",          LTYPEA, ARET,
375         "RFE",          LTYPEA, ARFE,
376
377         "TEXT",         LTYPEB, ATEXT,
378         "GLOBL",        LTYPEB, AGLOBL,
379         "DATA",         LTYPEC, ADATA,
380         "CASE",         LTYPED, ACASE,
381         "END",          LTYPEE, AEND,
382         "WORD",         LTYPEH, AWORD,
383         "NOP",          LTYPEI, ANOP,
384
385         "MCR",          LTYPEJ, 0,
386         "MRC",          LTYPEJ, 1,
387         0
388 };
389
390 void
391 cinit(void)
392 {
393         Sym *s;
394         int i;
395
396         nullgen.sym = S;
397         nullgen.offset = 0;
398         nullgen.type = D_NONE;
399         nullgen.name = D_NONE;
400         nullgen.reg = NREG;
401         if(FPCHIP)
402                 nullgen.dval = 0;
403         for(i=0; i<sizeof(nullgen.sval); i++)
404                 nullgen.sval[i] = 0;
405
406         nerrors = 0;
407         iostack = I;
408         iofree = I;
409         peekc = IGN;
410         nhunk = 0;
411         for(i=0; i<NHASH; i++)
412                 hash[i] = S;
413         for(i=0; itab[i].name; i++) {
414                 s = slookup(itab[i].name);
415                 s->type = itab[i].type;
416                 s->value = itab[i].value;
417         }
418
419         pathname = allocn(pathname, 0, 100);
420         if(mygetwd(pathname, 99) == 0) {
421                 pathname = allocn(pathname, 100, 900);
422                 if(mygetwd(pathname, 999) == 0)
423                         strcpy(pathname, "/???");
424         }
425 }
426
427 void
428 syminit(Sym *s)
429 {
430
431         s->type = LNAME;
432         s->value = 0;
433 }
434
435 int
436 isreg(Gen *g)
437 {
438
439         USED(g);
440         return 1;
441 }
442
443 void
444 cclean(void)
445 {
446
447         outcode(AEND, Always, &nullgen, NREG, &nullgen);
448         Bflush(&obuf);
449 }
450
451 void
452 zname(char *n, int t, int s)
453 {
454
455         Bputc(&obuf, ANAME);
456         Bputc(&obuf, t);        /* type */
457         Bputc(&obuf, s);        /* sym */
458         while(*n) {
459                 Bputc(&obuf, *n);
460                 n++;
461         }
462         Bputc(&obuf, 0);
463 }
464
465 void
466 zaddr(Gen *a, int s)
467 {
468         long l;
469         int i;
470         char *n;
471         Ieee e;
472
473         Bputc(&obuf, a->type);
474         Bputc(&obuf, a->reg);
475         Bputc(&obuf, s);
476         Bputc(&obuf, a->name);
477         switch(a->type) {
478         default:
479                 print("unknown type %d\n", a->type);
480                 exits("arg");
481
482         case D_NONE:
483         case D_REG:
484         case D_FREG:
485         case D_PSR:
486         case D_FPCR:
487                 break;
488
489         case D_REGREG:
490                 Bputc(&obuf, a->offset);
491                 break;
492
493         case D_OREG:
494         case D_CONST:
495         case D_BRANCH:
496         case D_SHIFT:
497                 l = a->offset;
498                 Bputc(&obuf, l);
499                 Bputc(&obuf, l>>8);
500                 Bputc(&obuf, l>>16);
501                 Bputc(&obuf, l>>24);
502                 break;
503
504         case D_SCONST:
505                 n = a->sval;
506                 for(i=0; i<NSNAME; i++) {
507                         Bputc(&obuf, *n);
508                         n++;
509                 }
510                 break;
511
512         case D_FCONST:
513                 ieeedtod(&e, a->dval);
514                 Bputc(&obuf, e.l);
515                 Bputc(&obuf, e.l>>8);
516                 Bputc(&obuf, e.l>>16);
517                 Bputc(&obuf, e.l>>24);
518                 Bputc(&obuf, e.h);
519                 Bputc(&obuf, e.h>>8);
520                 Bputc(&obuf, e.h>>16);
521                 Bputc(&obuf, e.h>>24);
522                 break;
523         }
524 }
525
526 static int bcode[] =
527 {
528         ABEQ,
529         ABNE,
530         ABCS,
531         ABCC,
532         ABMI,
533         ABPL,
534         ABVS,
535         ABVC,
536         ABHI,
537         ABLS,
538         ABGE,
539         ABLT,
540         ABGT,
541         ABLE,
542         AB,
543         ANOP,
544 };
545
546 void
547 outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
548 {
549         int sf, st, t;
550         Sym *s;
551
552         /* hack to make B.NE etc. work: turn it into the corresponding conditional */
553         if(a == AB){
554                 a = bcode[scond&0xf];
555                 scond = (scond & ~0xf) | Always;
556         }
557
558         if(pass == 1)
559                 goto out;
560 jackpot:
561         sf = 0;
562         s = g1->sym;
563         while(s != S) {
564                 sf = s->sym;
565                 if(sf < 0 || sf >= NSYM)
566                         sf = 0;
567                 t = g1->name;
568                 if(h[sf].type == t)
569                 if(h[sf].sym == s)
570                         break;
571                 zname(s->name, t, sym);
572                 s->sym = sym;
573                 h[sym].sym = s;
574                 h[sym].type = t;
575                 sf = sym;
576                 sym++;
577                 if(sym >= NSYM)
578                         sym = 1;
579                 break;
580         }
581         st = 0;
582         s = g2->sym;
583         while(s != S) {
584                 st = s->sym;
585                 if(st < 0 || st >= NSYM)
586                         st = 0;
587                 t = g2->name;
588                 if(h[st].type == t)
589                 if(h[st].sym == s)
590                         break;
591                 zname(s->name, t, sym);
592                 s->sym = sym;
593                 h[sym].sym = s;
594                 h[sym].type = t;
595                 st = sym;
596                 sym++;
597                 if(sym >= NSYM)
598                         sym = 1;
599                 if(st == sf)
600                         goto jackpot;
601                 break;
602         }
603         Bputc(&obuf, a);
604         Bputc(&obuf, scond);
605         Bputc(&obuf, reg);
606         Bputc(&obuf, lineno);
607         Bputc(&obuf, lineno>>8);
608         Bputc(&obuf, lineno>>16);
609         Bputc(&obuf, lineno>>24);
610         zaddr(g1, sf);
611         zaddr(g2, st);
612
613 out:
614         if(a != AGLOBL && a != ADATA)
615                 pc++;
616 }
617
618 void
619 outhist(void)
620 {
621         Gen g;
622         Hist *h;
623         char *p, *q, *op, c;
624         int n;
625
626         g = nullgen;
627         c = pathchar();
628         for(h = hist; h != H; h = h->link) {
629                 p = h->name;
630                 op = 0;
631                 /* on windows skip drive specifier in pathname */
632                 if(systemtype(Windows) && p && p[1] == ':'){
633                         p += 2;
634                         c = *p;
635                 }
636                 if(p && p[0] != c && h->offset == 0 && pathname){
637                         /* on windows skip drive specifier in pathname */
638                         if(systemtype(Windows) && pathname[1] == ':') {
639                                 op = p;
640                                 p = pathname+2;
641                                 c = *p;
642                         } else if(pathname[0] == c){
643                                 op = p;
644                                 p = pathname;
645                         }
646                 }
647                 while(p) {
648                         q = strchr(p, c);
649                         if(q) {
650                                 n = q-p;
651                                 if(n == 0){
652                                         n = 1;  /* leading "/" */
653                                         *p = '/';       /* don't emit "\" on windows */
654                                 }
655                                 q++;
656                         } else {
657                                 n = strlen(p);
658                                 q = 0;
659                         }
660                         if(n) {
661                                 Bputc(&obuf, ANAME);
662                                 Bputc(&obuf, D_FILE);   /* type */
663                                 Bputc(&obuf, 1);        /* sym */
664                                 Bputc(&obuf, '<');
665                                 Bwrite(&obuf, p, n);
666                                 Bputc(&obuf, 0);
667                         }
668                         p = q;
669                         if(p == 0 && op) {
670                                 p = op;
671                                 op = 0;
672                         }
673                 }
674                 g.offset = h->offset;
675
676                 Bputc(&obuf, AHISTORY);
677                 Bputc(&obuf, Always);
678                 Bputc(&obuf, 0);
679                 Bputc(&obuf, h->line);
680                 Bputc(&obuf, h->line>>8);
681                 Bputc(&obuf, h->line>>16);
682                 Bputc(&obuf, h->line>>24);
683                 zaddr(&nullgen, 0);
684                 zaddr(&g, 0);
685         }
686 }
687
688 #include "../cc/lexbody"
689 #include "../cc/macbody"
690 #include "../cc/compat"