123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #define EXTERN
- #include "a.h"
- #include "y.tab.h"
- #include <ctype.h>
- void
- main(int argc, char *argv[])
- {
- char *p;
- int nout, nproc, status, i, c;
- thechar = '5';
- thestring = "arm";
- memset(debug, 0, sizeof(debug));
- cinit();
- outfile = 0;
- include[ninclude++] = ".";
- ARGBEGIN {
- default:
- c = ARGC();
- if(c >= 0 || c < sizeof(debug))
- debug[c] = 1;
- break;
- case 'o':
- outfile = ARGF();
- break;
- case 'D':
- p = ARGF();
- if(p)
- Dlist[nDlist++] = p;
- break;
- case 'I':
- p = ARGF();
- setinclude(p);
- break;
- case 't':
- thechar = 't';
- thestring = "thumb";
- break;
- } ARGEND
- if(*argv == 0) {
- print("usage: %ca [-options] file.s\n", thechar);
- errorexit();
- }
- if(argc > 1 && systemtype(Windows)){
- print("can't assemble multiple files on windows\n");
- errorexit();
- }
- if(argc > 1 && !systemtype(Windows)) {
- nproc = 1;
- if(p = getenv("NPROC"))
- nproc = atol(p); /* */
- c = 0;
- nout = 0;
- for(;;) {
- while(nout < nproc && argc > 0) {
- i = myfork();
- if(i < 0) {
- i = mywait(&status);
- if(i < 0)
- errorexit();
- if(status)
- c++;
- nout--;
- continue;
- }
- if(i == 0) {
- print("%s:\n", *argv);
- if(assemble(*argv))
- errorexit();
- exits(0);
- }
- nout++;
- argc--;
- argv++;
- }
- i = mywait(&status);
- if(i < 0) {
- if(c)
- errorexit();
- exits(0);
- }
- if(status)
- c++;
- nout--;
- }
- }
- if(assemble(argv[0]))
- errorexit();
- exits(0);
- }
- int
- assemble(char *file)
- {
- char ofile[100], incfile[20], *p;
- int i, of;
- strcpy(ofile, file);
- p = utfrrune(ofile, pathchar());
- if(p) {
- include[0] = ofile;
- *p++ = 0;
- } else
- p = ofile;
- if(outfile == 0) {
- outfile = p;
- if(outfile){
- p = utfrrune(outfile, '.');
- if(p)
- if(p[1] == 's' && p[2] == 0)
- p[0] = 0;
- p = utfrune(outfile, 0);
- p[0] = '.';
- p[1] = thechar;
- p[2] = 0;
- } else
- outfile = "/dev/null";
- }
- p = getenv("INCLUDE");
- if(p) {
- setinclude(p);
- } else {
- if(systemtype(Plan9)) {
- sprint(incfile,"/%s/include", thestring);
- setinclude(strdup(incfile));
- }
- }
- of = mycreat(outfile, 0664);
- if(of < 0) {
- yyerror("%ca: cannot create %s", thechar, outfile);
- errorexit();
- }
- Binit(&obuf, of, OWRITE);
- pass = 1;
- pinit(file);
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- if(nerrors) {
- cclean();
- return nerrors;
- }
- pass = 2;
- outhist();
- pinit(file);
- for(i=0; i<nDlist; i++)
- dodefine(Dlist[i]);
- yyparse();
- cclean();
- return nerrors;
- }
- struct
- {
- char *name;
- uint16_t type;
- uint16_t value;
- } itab[] =
- {
- "SP", LSP, D_AUTO,
- "SB", LSB, D_EXTERN,
- "FP", LFP, D_PARAM,
- "PC", LPC, D_BRANCH,
- "R", LR, 0,
- "R0", LREG, 0,
- "R1", LREG, 1,
- "R2", LREG, 2,
- "R3", LREG, 3,
- "R4", LREG, 4,
- "R5", LREG, 5,
- "R6", LREG, 6,
- "R7", LREG, 7,
- "R8", LREG, 8,
- "R9", LREG, 9,
- "R10", LREG, 10,
- "R11", LREG, 11,
- "R12", LREG, 12,
- "R13", LREG, 13,
- "R14", LREG, 14,
- "R15", LREG, 15,
- "F", LF, 0,
- "F0", LFREG, 0,
- "F1", LFREG, 1,
- "F2", LFREG, 2,
- "F3", LFREG, 3,
- "F4", LFREG, 4,
- "F5", LFREG, 5,
- "F6", LFREG, 6,
- "F7", LFREG, 7,
- "F8", LFREG, 8,
- "F9", LFREG, 9,
- "F10", LFREG, 10,
- "F11", LFREG, 11,
- "F12", LFREG, 12,
- "F13", LFREG, 13,
- "F14", LFREG, 14,
- "F15", LFREG, 15,
- "C", LC, 0,
- "C0", LCREG, 0,
- "C1", LCREG, 1,
- "C2", LCREG, 2,
- "C3", LCREG, 3,
- "C4", LCREG, 4,
- "C5", LCREG, 5,
- "C6", LCREG, 6,
- "C7", LCREG, 7,
- "C8", LCREG, 8,
- "C9", LCREG, 9,
- "C10", LCREG, 10,
- "C11", LCREG, 11,
- "C12", LCREG, 12,
- "C13", LCREG, 13,
- "C14", LCREG, 14,
- "C15", LCREG, 15,
- "CPSR", LPSR, 0,
- "SPSR", LPSR, 1,
- "FPSR", LFCR, 0,
- "FPCR", LFCR, 1,
- ".EQ", LCOND, 0,
- ".NE", LCOND, 1,
- ".CS", LCOND, 2,
- ".HS", LCOND, 2,
- ".CC", LCOND, 3,
- ".LO", LCOND, 3,
- ".MI", LCOND, 4,
- ".PL", LCOND, 5,
- ".VS", LCOND, 6,
- ".VC", LCOND, 7,
- ".HI", LCOND, 8,
- ".LS", LCOND, 9,
- ".GE", LCOND, 10,
- ".LT", LCOND, 11,
- ".GT", LCOND, 12,
- ".LE", LCOND, 13,
- ".AL", LCOND, Always,
- ".U", LS, C_UBIT,
- ".S", LS, C_SBIT,
- ".W", LS, C_WBIT,
- ".P", LS, C_PBIT,
- ".PW", LS, C_WBIT|C_PBIT,
- ".WP", LS, C_WBIT|C_PBIT,
- ".F", LS, C_FBIT,
- ".IBW", LS, C_WBIT|C_PBIT|C_UBIT,
- ".IAW", LS, C_WBIT|C_UBIT,
- ".DBW", LS, C_WBIT|C_PBIT,
- ".DAW", LS, C_WBIT,
- ".IB", LS, C_PBIT|C_UBIT,
- ".IA", LS, C_UBIT,
- ".DB", LS, C_PBIT,
- ".DA", LS, 0,
- "@", LAT, 0,
- "AND", LTYPE1, AAND,
- "EOR", LTYPE1, AEOR,
- "SUB", LTYPE1, ASUB,
- "RSB", LTYPE1, ARSB,
- "ADD", LTYPE1, AADD,
- "ADC", LTYPE1, AADC,
- "SBC", LTYPE1, ASBC,
- "RSC", LTYPE1, ARSC,
- "ORR", LTYPE1, AORR,
- "BIC", LTYPE1, ABIC,
- "SLL", LTYPE1, ASLL,
- "SRL", LTYPE1, ASRL,
- "SRA", LTYPE1, ASRA,
- "MUL", LTYPE1, AMUL,
- "MULA", LTYPEN, AMULA,
- "DIV", LTYPE1, ADIV,
- "MOD", LTYPE1, AMOD,
- "MULL", LTYPEM, AMULL,
- "MULAL", LTYPEM, AMULAL,
- "MULLU", LTYPEM, AMULLU,
- "MULALU", LTYPEM, AMULALU,
- "MVN", LTYPE2, AMVN, /* op2 ignored */
- "MOVB", LTYPE3, AMOVB,
- "MOVBU", LTYPE3, AMOVBU,
- "MOVH", LTYPE3, AMOVH,
- "MOVHU", LTYPE3, AMOVHU,
- "MOVW", LTYPE3, AMOVW,
- "MOVD", LTYPE3, AMOVD,
- "MOVDF", LTYPE3, AMOVDF,
- "MOVDW", LTYPE3, AMOVDW,
- "MOVF", LTYPE3, AMOVF,
- "MOVFD", LTYPE3, AMOVFD,
- "MOVFW", LTYPE3, AMOVFW,
- "MOVWD", LTYPE3, AMOVWD,
- "MOVWF", LTYPE3, AMOVWF,
- "LDREX", LTYPE3, ALDREX,
- "LDREXD", LTYPE3, ALDREXD,
- "STREX", LTYPE9, ASTREX,
- "STREXD", LTYPE9, ASTREXD,
- /*
- "ABSF", LTYPEI, AABSF,
- "ABSD", LTYPEI, AABSD,
- "NEGF", LTYPEI, ANEGF,
- "NEGD", LTYPEI, ANEGD,
- "SQTF", LTYPEI, ASQTF,
- "SQTD", LTYPEI, ASQTD,
- "RNDF", LTYPEI, ARNDF,
- "RNDD", LTYPEI, ARNDD,
- "URDF", LTYPEI, AURDF,
- "URDD", LTYPEI, AURDD,
- "NRMF", LTYPEI, ANRMF,
- "NRMD", LTYPEI, ANRMD,
- */
- "SQRTF", LTYPEI, ASQRTF,
- "SQRTD", LTYPEI, ASQRTD,
- "CMPF", LTYPEL, ACMPF,
- "CMPD", LTYPEL, ACMPD,
- "ADDF", LTYPEK, AADDF,
- "ADDD", LTYPEK, AADDD,
- "SUBF", LTYPEK, ASUBF,
- "SUBD", LTYPEK, ASUBD,
- "MULF", LTYPEK, AMULF,
- "MULD", LTYPEK, AMULD,
- "DIVF", LTYPEK, ADIVF,
- "DIVD", LTYPEK, ADIVD,
- "B", LTYPE4, AB,
- "BL", LTYPE4, ABL,
- "BX", LTYPEBX, ABX,
- "BEQ", LTYPE5, ABEQ,
- "BNE", LTYPE5, ABNE,
- "BCS", LTYPE5, ABCS,
- "BHS", LTYPE5, ABHS,
- "BCC", LTYPE5, ABCC,
- "BLO", LTYPE5, ABLO,
- "BMI", LTYPE5, ABMI,
- "BPL", LTYPE5, ABPL,
- "BVS", LTYPE5, ABVS,
- "BVC", LTYPE5, ABVC,
- "BHI", LTYPE5, ABHI,
- "BLS", LTYPE5, ABLS,
- "BGE", LTYPE5, ABGE,
- "BLT", LTYPE5, ABLT,
- "BGT", LTYPE5, ABGT,
- "BLE", LTYPE5, ABLE,
- "BCASE", LTYPE5, ABCASE,
- "SWI", LTYPE6, ASWI,
- "CMP", LTYPE7, ACMP,
- "TST", LTYPE7, ATST,
- "TEQ", LTYPE7, ATEQ,
- "CMN", LTYPE7, ACMN,
- "MOVM", LTYPE8, AMOVM,
- "SWPBU", LTYPE9, ASWPBU,
- "SWPW", LTYPE9, ASWPW,
- "RET", LTYPEA, ARET,
- "RFE", LTYPEA, ARFE,
- "TEXT", LTYPEB, ATEXT,
- "GLOBL", LTYPEB, AGLOBL,
- "DATA", LTYPEC, ADATA,
- "CASE", LTYPED, ACASE,
- "END", LTYPEE, AEND,
- "WORD", LTYPEH, AWORD,
- "NOP", LTYPEI, ANOP,
- "MCR", LTYPEJ, 0,
- "MRC", LTYPEJ, 1,
- 0
- };
- void
- cinit(void)
- {
- Sym *s;
- int i;
- nullgen.sym = S;
- nullgen.offset = 0;
- nullgen.type = D_NONE;
- nullgen.name = D_NONE;
- nullgen.reg = NREG;
- if(FPCHIP)
- nullgen.dval = 0;
- for(i=0; i<sizeof(nullgen.sval); i++)
- nullgen.sval[i] = 0;
- nerrors = 0;
- iostack = I;
- iofree = I;
- peekc = IGN;
- nhunk = 0;
- for(i=0; i<NHASH; i++)
- hash[i] = S;
- for(i=0; itab[i].name; i++) {
- s = slookup(itab[i].name);
- s->type = itab[i].type;
- s->value = itab[i].value;
- }
- pathname = allocn(pathname, 0, 100);
- if(getwd(pathname, 99) == 0) {
- pathname = allocn(pathname, 100, 900);
- if(getwd(pathname, 999) == 0)
- strcpy(pathname, "/???");
- }
- }
- void
- syminit(Sym *s)
- {
- s->type = LNAME;
- s->value = 0;
- }
- int
- isreg(Gen *g)
- {
- USED(g);
- return 1;
- }
- void
- cclean(void)
- {
- outcode(AEND, Always, &nullgen, NREG, &nullgen);
- Bflush(&obuf);
- }
- void
- zname(char *n, int t, int s)
- {
- Bputc(&obuf, ANAME);
- Bputc(&obuf, t); /* type */
- Bputc(&obuf, s); /* sym */
- while(*n) {
- Bputc(&obuf, *n);
- n++;
- }
- Bputc(&obuf, 0);
- }
- void
- zaddr(Gen *a, int s)
- {
- int32_t l;
- int i;
- char *n;
- Ieee e;
- Bputc(&obuf, a->type);
- Bputc(&obuf, a->reg);
- Bputc(&obuf, s);
- Bputc(&obuf, a->name);
- switch(a->type) {
- default:
- print("unknown type %d\n", a->type);
- exits("arg");
- case D_NONE:
- case D_REG:
- case D_FREG:
- case D_PSR:
- case D_FPCR:
- break;
- case D_REGREG:
- Bputc(&obuf, a->offset);
- break;
- case D_OREG:
- case D_CONST:
- case D_BRANCH:
- case D_SHIFT:
- l = a->offset;
- Bputc(&obuf, l);
- Bputc(&obuf, l>>8);
- Bputc(&obuf, l>>16);
- Bputc(&obuf, l>>24);
- break;
- case D_SCONST:
- n = a->sval;
- for(i=0; i<NSNAME; i++) {
- Bputc(&obuf, *n);
- n++;
- }
- break;
- case D_FCONST:
- ieeedtod(&e, a->dval);
- Bputc(&obuf, e.l);
- Bputc(&obuf, e.l>>8);
- Bputc(&obuf, e.l>>16);
- Bputc(&obuf, e.l>>24);
- Bputc(&obuf, e.h);
- Bputc(&obuf, e.h>>8);
- Bputc(&obuf, e.h>>16);
- Bputc(&obuf, e.h>>24);
- break;
- }
- }
- static int bcode[] =
- {
- ABEQ,
- ABNE,
- ABCS,
- ABCC,
- ABMI,
- ABPL,
- ABVS,
- ABVC,
- ABHI,
- ABLS,
- ABGE,
- ABLT,
- ABGT,
- ABLE,
- AB,
- ANOP,
- };
- void
- outcode(int a, int scond, Gen *g1, int reg, Gen *g2)
- {
- int sf, st, t;
- Sym *s;
- /* hack to make B.NE etc. work: turn it into the corresponding conditional */
- if(a == AB){
- a = bcode[scond&0xf];
- scond = (scond & ~0xf) | Always;
- }
- if(pass == 1)
- goto out;
- jackpot:
- sf = 0;
- s = g1->sym;
- while(s != S) {
- sf = s->sym;
- if(sf < 0 || sf >= NSYM)
- sf = 0;
- t = g1->name;
- if(h[sf].type == t)
- if(h[sf].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- sf = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- break;
- }
- st = 0;
- s = g2->sym;
- while(s != S) {
- st = s->sym;
- if(st < 0 || st >= NSYM)
- st = 0;
- t = g2->name;
- if(h[st].type == t)
- if(h[st].sym == s)
- break;
- zname(s->name, t, sym);
- s->sym = sym;
- h[sym].sym = s;
- h[sym].type = t;
- st = sym;
- sym++;
- if(sym >= NSYM)
- sym = 1;
- if(st == sf)
- goto jackpot;
- break;
- }
- Bputc(&obuf, a);
- Bputc(&obuf, scond);
- Bputc(&obuf, reg);
- Bputc(&obuf, lineno);
- Bputc(&obuf, lineno>>8);
- Bputc(&obuf, lineno>>16);
- Bputc(&obuf, lineno>>24);
- zaddr(g1, sf);
- zaddr(g2, st);
- out:
- if(a != AGLOBL && a != ADATA)
- pc++;
- }
- void
- outhist(void)
- {
- Gen g;
- Hist *h;
- char *p, *q, *op, c;
- int n;
- g = nullgen;
- c = pathchar();
- for(h = hist; h != H; h = h->link) {
- p = h->name;
- op = 0;
- /* on windows skip drive specifier in pathname */
- if(systemtype(Windows) && p && p[1] == ':'){
- p += 2;
- c = *p;
- }
- if(p && p[0] != c && h->offset == 0 && pathname){
- /* on windows skip drive specifier in pathname */
- if(systemtype(Windows) && pathname[1] == ':') {
- op = p;
- p = pathname+2;
- c = *p;
- } else if(pathname[0] == c){
- op = p;
- p = pathname;
- }
- }
- while(p) {
- q = strchr(p, c);
- if(q) {
- n = q-p;
- if(n == 0){
- n = 1; /* leading "/" */
- *p = '/'; /* don't emit "\" on windows */
- }
- q++;
- } else {
- n = strlen(p);
- q = 0;
- }
- if(n) {
- Bputc(&obuf, ANAME);
- Bputc(&obuf, D_FILE); /* type */
- Bputc(&obuf, 1); /* sym */
- Bputc(&obuf, '<');
- Bwrite(&obuf, p, n);
- Bputc(&obuf, 0);
- }
- p = q;
- if(p == 0 && op) {
- p = op;
- op = 0;
- }
- }
- g.offset = h->offset;
- Bputc(&obuf, AHISTORY);
- Bputc(&obuf, Always);
- Bputc(&obuf, 0);
- Bputc(&obuf, h->line);
- Bputc(&obuf, h->line>>8);
- Bputc(&obuf, h->line>>16);
- Bputc(&obuf, h->line>>24);
- zaddr(&nullgen, 0);
- zaddr(&g, 0);
- }
- }
- #include "../cc/lexbody"
- #include "../cc/macbody"
- #include "../cc/compat"
|