123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- /*
- * common code for all the assemblers
- */
- void
- pragpack(void)
- {
- while(getnsc() != '\n')
- ;
- }
- void
- pragvararg(void)
- {
- while(getnsc() != '\n')
- ;
- }
- void
- pragfpround(void)
- {
- while(getnsc() != '\n')
- ;
- }
- void
- pragprofile(void)
- {
- while(getnsc() != '\n')
- ;
- }
- void
- pragincomplete(void)
- {
- while(getnsc() != '\n')
- ;
- }
- /*
- * real allocs
- */
- void*
- alloc(long n)
- {
- void *p;
- while((uintptr)hunk & MAXALIGN) {
- hunk++;
- nhunk--;
- }
- while(nhunk < n)
- gethunk();
- p = hunk;
- nhunk -= n;
- hunk += n;
- return p;
- }
- void*
- allocn(void *p, long on, long n)
- {
- void *q;
- q = (uchar*)p + on;
- if(q != hunk || nhunk < n) {
- while(nhunk < on+n)
- gethunk();
- memmove(hunk, p, on);
- p = hunk;
- hunk += on;
- nhunk -= on;
- }
- hunk += n;
- nhunk -= n;
- return p;
- }
- void
- setinclude(char *p)
- {
- int i;
- if(p == 0)
- return;
- for(i=1; i < ninclude; i++)
- if(strcmp(p, include[i]) == 0)
- return;
- if(ninclude >= nelem(include)) {
- yyerror("ninclude too small %d", nelem(include));
- exits("ninclude");
- }
- include[ninclude++] = p;
- }
- void
- errorexit(void)
- {
- if(outfile)
- remove(outfile);
- exits("error");
- }
- void
- pushio(void)
- {
- Io *i;
- i = iostack;
- if(i == I) {
- yyerror("botch in pushio");
- errorexit();
- }
- i->p = fi.p;
- i->c = fi.c;
- }
- void
- newio(void)
- {
- Io *i;
- static int pushdepth = 0;
- i = iofree;
- if(i == I) {
- pushdepth++;
- if(pushdepth > 1000) {
- yyerror("macro/io expansion too deep");
- errorexit();
- }
- i = alloc(sizeof(*i));
- } else
- iofree = i->link;
- i->c = 0;
- i->f = -1;
- ionext = i;
- }
- void
- newfile(char *s, int f)
- {
- Io *i;
- i = ionext;
- i->link = iostack;
- iostack = i;
- i->f = f;
- if(f < 0)
- i->f = open(s, 0);
- if(i->f < 0) {
- yyerror("%ca: %r: %s", thechar, s);
- errorexit();
- }
- fi.c = 0;
- linehist(s, 0);
- }
- Sym*
- slookup(char *s)
- {
- strcpy(symb, s);
- return lookup();
- }
- Sym*
- lookup(void)
- {
- Sym *s;
- long h;
- char *p;
- int c, l;
- h = 0;
- for(p=symb; c = *p; p++)
- h = h+h+h + c;
- l = (p - symb) + 1;
- if(h < 0)
- h = ~h;
- h %= NHASH;
- c = symb[0];
- for(s = hash[h]; s != S; s = s->link) {
- if(s->name[0] != c)
- continue;
- if(memcmp(s->name, symb, l) == 0)
- return s;
- }
- s = alloc(sizeof(*s));
- s->name = alloc(l);
- memmove(s->name, symb, l);
- s->link = hash[h];
- hash[h] = s;
- syminit(s);
- return s;
- }
- long
- yylex(void)
- {
- int c, c1;
- char *cp;
- Sym *s;
- c = peekc;
- if(c != IGN) {
- peekc = IGN;
- goto l1;
- }
- l0:
- c = GETC();
- l1:
- if(c == EOF) {
- peekc = EOF;
- return -1;
- }
- if(isspace(c)) {
- if(c == '\n') {
- lineno++;
- return ';';
- }
- goto l0;
- }
- if(isalpha(c))
- goto talph;
- if(isdigit(c))
- goto tnum;
- switch(c)
- {
- case '\n':
- lineno++;
- return ';';
- case '#':
- domacro();
- goto l0;
- case '.':
- c = GETC();
- if(isalpha(c)) {
- cp = symb;
- *cp++ = '.';
- goto aloop;
- }
- if(isdigit(c)) {
- cp = symb;
- *cp++ = '.';
- goto casedot;
- }
- peekc = c;
- return '.';
- talph:
- case '_':
- case '@':
- cp = symb;
- aloop:
- *cp++ = c;
- c = GETC();
- if(isalpha(c) || isdigit(c) || c == '_' || c == '$')
- goto aloop;
- *cp = 0;
- peekc = c;
- s = lookup();
- if(s->macro) {
- newio();
- cp = ionext->b;
- macexpand(s, cp);
- pushio();
- ionext->link = iostack;
- iostack = ionext;
- fi.p = cp;
- fi.c = strlen(cp);
- if(peekc != IGN) {
- cp[fi.c++] = peekc;
- cp[fi.c] = 0;
- peekc = IGN;
- }
- goto l0;
- }
- if(s->type == 0)
- s->type = LNAME;
- if(s->type == LNAME ||
- s->type == LVAR ||
- s->type == LLAB) {
- yylval.sym = s;
- return s->type;
- }
- yylval.lval = s->value;
- return s->type;
- tnum:
- cp = symb;
- if(c != '0')
- goto dc;
- *cp++ = c;
- c = GETC();
- c1 = 3;
- if(c == 'x' || c == 'X') {
- c1 = 4;
- c = GETC();
- } else
- if(c < '0' || c > '7')
- goto dc;
- yylval.lval = 0;
- for(;;) {
- if(c >= '0' && c <= '9') {
- if(c > '7' && c1 == 3)
- break;
- yylval.lval <<= c1;
- yylval.lval += c - '0';
- c = GETC();
- continue;
- }
- if(c1 == 3)
- break;
- if(c >= 'A' && c <= 'F')
- c += 'a' - 'A';
- if(c >= 'a' && c <= 'f') {
- yylval.lval <<= c1;
- yylval.lval += c - 'a' + 10;
- c = GETC();
- continue;
- }
- break;
- }
- goto ncu;
- dc:
- for(;;) {
- if(!isdigit(c))
- break;
- *cp++ = c;
- c = GETC();
- }
- if(c == '.')
- goto casedot;
- if(c == 'e' || c == 'E')
- goto casee;
- *cp = 0;
- if(sizeof(yylval.lval) == sizeof(vlong))
- yylval.lval = strtoll(symb, nil, 10);
- else
- yylval.lval = strtol(symb, nil, 10);
- ncu:
- while(c == 'U' || c == 'u' || c == 'l' || c == 'L')
- c = GETC();
- peekc = c;
- return LCONST;
- casedot:
- for(;;) {
- *cp++ = c;
- c = GETC();
- if(!isdigit(c))
- break;
- }
- if(c == 'e' || c == 'E')
- goto casee;
- goto caseout;
- casee:
- *cp++ = 'e';
- c = GETC();
- if(c == '+' || c == '-') {
- *cp++ = c;
- c = GETC();
- }
- while(isdigit(c)) {
- *cp++ = c;
- c = GETC();
- }
- caseout:
- *cp = 0;
- peekc = c;
- if(FPCHIP) {
- yylval.dval = atof(symb);
- return LFCONST;
- }
- yyerror("assembler cannot interpret fp constants");
- yylval.lval = 1L;
- return LCONST;
- case '"':
- memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval));
- cp = yylval.sval;
- c1 = 0;
- for(;;) {
- c = escchar('"');
- if(c == EOF)
- break;
- if(c1 < sizeof(yylval.sval))
- *cp++ = c;
- c1++;
- }
- if(c1 > sizeof(yylval.sval))
- yyerror("string constant too long");
- return LSCONST;
- case '\'':
- c = escchar('\'');
- if(c == EOF)
- c = '\'';
- if(escchar('\'') != EOF)
- yyerror("missing '");
- yylval.lval = c;
- return LCONST;
- case '/':
- c1 = GETC();
- if(c1 == '/') {
- for(;;) {
- c = GETC();
- if(c == '\n')
- goto l1;
- if(c == EOF) {
- yyerror("eof in comment");
- errorexit();
- }
- }
- }
- if(c1 == '*') {
- for(;;) {
- c = GETC();
- while(c == '*') {
- c = GETC();
- if(c == '/')
- goto l0;
- }
- if(c == EOF) {
- yyerror("eof in comment");
- errorexit();
- }
- if(c == '\n')
- lineno++;
- }
- }
- break;
- default:
- return c;
- }
- peekc = c1;
- return c;
- }
- int
- getc(void)
- {
- int c;
- c = peekc;
- if(c != IGN) {
- peekc = IGN;
- return c;
- }
- c = GETC();
- if(c == '\n')
- lineno++;
- if(c == EOF) {
- yyerror("End of file");
- errorexit();
- }
- return c;
- }
- int
- getnsc(void)
- {
- int c;
- for(;;) {
- c = getc();
- if(!isspace(c) || c == '\n')
- return c;
- }
- }
- void
- unget(int c)
- {
- peekc = c;
- if(c == '\n')
- lineno--;
- }
- int
- escchar(int e)
- {
- int c, l;
- loop:
- c = getc();
- if(c == '\n') {
- yyerror("newline in string");
- return EOF;
- }
- if(c != '\\') {
- if(c == e)
- return EOF;
- return c;
- }
- c = getc();
- if(c >= '0' && c <= '7') {
- l = c - '0';
- c = getc();
- if(c >= '0' && c <= '7') {
- l = l*8 + c-'0';
- c = getc();
- if(c >= '0' && c <= '7') {
- l = l*8 + c-'0';
- return l;
- }
- }
- peekc = c;
- return l;
- }
- switch(c)
- {
- case '\n': goto loop;
- case 'n': return '\n';
- case 't': return '\t';
- case 'b': return '\b';
- case 'r': return '\r';
- case 'f': return '\f';
- case 'a': return 0x07;
- case 'v': return 0x0b;
- case 'z': return 0x00;
- }
- return c;
- }
- void
- pinit(char *f)
- {
- int i;
- Sym *s;
- lineno = 1;
- newio();
- newfile(f, -1);
- pc = 0;
- peekc = IGN;
- sym = 1;
- for(i=0; i<NSYM; i++) {
- h[i].type = 0;
- h[i].sym = S;
- }
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->link)
- s->macro = 0;
- }
- int
- filbuf(void)
- {
- Io *i;
- loop:
- i = iostack;
- if(i == I)
- return EOF;
- if(i->f < 0)
- goto pop;
- fi.c = read(i->f, i->b, BUFSIZ) - 1;
- if(fi.c < 0) {
- close(i->f);
- linehist(0, 0);
- goto pop;
- }
- fi.p = i->b + 1;
- return i->b[0];
- pop:
- iostack = i->link;
- i->link = iofree;
- iofree = i;
- i = iostack;
- if(i == I)
- return EOF;
- fi.p = i->p;
- fi.c = i->c;
- if(--fi.c < 0)
- goto loop;
- return *fi.p++;
- }
- void
- yyerror(char *a, ...)
- {
- char buf[200];
- va_list arg;
- /*
- * hack to intercept message from yaccpar
- */
- if(strcmp(a, "syntax error") == 0) {
- yyerror("syntax error, last name: %s", symb);
- return;
- }
- prfile(lineno);
- va_start(arg, a);
- vseprint(buf, buf+sizeof(buf), a, arg);
- va_end(arg);
- print("%s\n", buf);
- nerrors++;
- if(nerrors > 10) {
- print("too many errors\n");
- errorexit();
- }
- }
- void
- prfile(long l)
- {
- int i, n;
- Hist a[HISTSZ], *h;
- long d;
- n = 0;
- for(h = hist; h != H; h = h->link) {
- if(l < h->line)
- break;
- if(h->name) {
- if(h->offset == 0) {
- if(n >= 0 && n < HISTSZ)
- a[n] = *h;
- n++;
- continue;
- }
- if(n > 0 && n < HISTSZ)
- if(a[n-1].offset == 0) {
- a[n] = *h;
- n++;
- } else
- a[n-1] = *h;
- continue;
- }
- n--;
- if(n >= 0 && n < HISTSZ) {
- d = h->line - a[n].line;
- for(i=0; i<n; i++)
- a[i].line += d;
- }
- }
- if(n > HISTSZ)
- n = HISTSZ;
- for(i=0; i<n; i++)
- print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1));
- }
- void
- ieeedtod(Ieee *ieee, double native)
- {
- double fr, ho, f;
- int exp;
- if(native < 0) {
- ieeedtod(ieee, -native);
- ieee->h |= 0x80000000L;
- return;
- }
- if(native == 0) {
- ieee->l = 0;
- ieee->h = 0;
- return;
- }
- fr = frexp(native, &exp);
- f = 2097152L; /* shouldnt use fp constants here */
- fr = modf(fr*f, &ho);
- ieee->h = ho;
- ieee->h &= 0xfffffL;
- ieee->h |= (exp+1022L) << 20;
- f = 65536L;
- fr = modf(fr*f, &ho);
- ieee->l = ho;
- ieee->l <<= 16;
- ieee->l |= (long)(fr*f);
- }
|