diff options
Diffstat (limited to 'src/cmd/cc')
-rw-r--r-- | src/cmd/cc/cc.h | 38 | ||||
-rw-r--r-- | src/cmd/cc/lex.c | 127 | ||||
-rw-r--r-- | src/cmd/cc/lexbody | 76 | ||||
-rw-r--r-- | src/cmd/cc/macbody | 56 | ||||
-rw-r--r-- | src/cmd/cc/pgen.c | 133 | ||||
-rw-r--r-- | src/cmd/cc/pswt.c | 29 | ||||
-rw-r--r-- | src/cmd/cc/sub.c | 10 |
7 files changed, 165 insertions, 304 deletions
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h index af2339c97..c8aac1253 100644 --- a/src/cmd/cc/cc.h +++ b/src/cmd/cc/cc.h @@ -30,6 +30,7 @@ #include <libc.h> #include <bio.h> +#include <link.h> #ifndef EXTERN #define EXTERN extern @@ -48,13 +49,13 @@ typedef struct Type Type; typedef struct Funct Funct; typedef struct Decl Decl; typedef struct Io Io; -typedef struct Hist Hist; typedef struct Term Term; typedef struct Init Init; typedef struct Bits Bits; typedef struct Bvec Bvec; typedef struct Dynimp Dynimp; typedef struct Dynexp Dynexp; +typedef struct Var Var; typedef Rune TRune; /* target system type */ @@ -83,6 +84,14 @@ struct Bvec uint32 b[]; }; +struct Var +{ + vlong offset; + LSym* sym; + char name; + char etype; +}; + struct Node { Node* left; @@ -114,6 +123,7 @@ struct Node struct Sym { Sym* link; + LSym* lsym; Type* type; Type* suetag; Type* tenum; @@ -200,16 +210,6 @@ struct Io }; #define I ((Io*)0) -struct Hist -{ - Hist* link; - char* name; - int32 line; - int32 offset; -}; -#define H ((Hist*)0) -EXTERN Hist* hist; - struct Term { vlong mult; @@ -469,7 +469,6 @@ EXTERN int32 autoffset; EXTERN int blockno; EXTERN Decl* dclstack; EXTERN int debug[256]; -EXTERN Hist* ehist; EXTERN int32 firstbit; EXTERN Sym* firstarg; EXTERN Type* firstargtype; @@ -498,7 +497,6 @@ EXTERN int32 nsymb; EXTERN Biobuf outbuf; EXTERN Biobuf diagbuf; EXTERN char* outfile; -EXTERN char* pathname; EXTERN int peekc; EXTERN int32 stkoff; EXTERN Type* strf; @@ -508,8 +506,9 @@ EXTERN Sym* symstring; EXTERN int taggen; EXTERN Type* tfield; EXTERN Type* tufield; -EXTERN int thechar; -EXTERN char* thestring; +extern int thechar; +extern char* thestring; +extern LinkArch* thelinkarch; EXTERN Type* thisfn; EXTERN int32 thunk; EXTERN Type* types[NALLTYPES]; @@ -525,8 +524,11 @@ EXTERN int flag_largemodel; EXTERN int ncontin; EXTERN int canreach; EXTERN int warnreach; +EXTERN int nacl; EXTERN Bits zbits; EXTERN Fmt pragcgobuf; +EXTERN Biobuf bstdout; +EXTERN Var var[NVAR]; extern char *onames[], *tnames[], *gnames[]; extern char *cnames[], *qnames[], *bnames[]; @@ -556,6 +558,7 @@ extern uchar typechlpfd[]; EXTERN uchar* typeword; EXTERN uchar* typecmplx; +EXTERN Link* ctxt; extern uint32 thash1; extern uint32 thash2; @@ -603,6 +606,7 @@ int FNconv(Fmt*); int Oconv(Fmt*); int Qconv(Fmt*); int VBconv(Fmt*); +int Bconv(Fmt*); void setinclude(char*); /* @@ -612,7 +616,6 @@ void dodefine(char*); void domacro(void); Sym* getsym(void); int32 getnsn(void); -void linehist(char*, int); void macdef(void); void macprag(void); void macend(void); @@ -731,6 +734,7 @@ void diag(Node*, char*, ...); void warn(Node*, char*, ...); void yyerror(char*, ...); void fatal(Node*, char*, ...); +LSym* linksym(Sym*); /* * acid.c @@ -791,6 +795,7 @@ int32 exreg(Type*); int32 align(int32, Type*, int, int32*); int32 maxround(int32, int32); int hasdotdotdot(void); +void linkarchinit(void); extern schar ewidth[]; @@ -814,6 +819,7 @@ int machcap(Node*); #pragma varargck argpos diag 2 #pragma varargck argpos yyerror 1 +#pragma varargck type "B" Bits #pragma varargck type "F" Node* #pragma varargck type "L" int32 #pragma varargck type "Q" int32 diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c index 049dc5196..424843764 100644 --- a/src/cmd/cc/lex.c +++ b/src/cmd/cc/lex.c @@ -117,8 +117,28 @@ void main(int argc, char *argv[]) { int c; + char *p; + + // Allow GOARCH=thestring or GOARCH=thestringsuffix, + // but not other values. + p = getgoarch(); + if(strncmp(p, thestring, strlen(thestring)) != 0) + sysfatal("cannot use %cc with GOARCH=%s", thechar, p); + if(strcmp(p, "amd64p32") == 0) // must be before cinit + ewidth[TIND] = 4; + + nacl = strcmp(getgoos(), "nacl") == 0; + if(nacl) + flag_largemodel = 1; quotefmtinstall(); // before cinit, which overrides %Q + + linkarchinit(); + ctxt = linknew(thelinkarch); + ctxt->diag = yyerror; + ctxt->bso = &bstdout; + Binit(&bstdout, 1, OWRITE); + ensuresymb(NSYMB); memset(debug, 0, sizeof(debug)); tinit(); @@ -175,12 +195,14 @@ main(int argc, char *argv[]) flagcount("q", "print Go definitions", &debug['q']); flagcount("s", "print #define assembly offsets", &debug['s']); flagcount("t", "debug code generation", &debug['t']); + flagstr("trimpath", "prefix: remove prefix from recorded source file paths", &ctxt->trimpath); flagcount("w", "enable warnings", &debug['w']); flagcount("v", "increase debug verbosity", &debug['v']); if(thechar == '6') flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel); flagparse(&argc, &argv, usage); + ctxt->debugasm = debug['S']; if(argc < 1 && outfile == 0) usage(); @@ -195,6 +217,7 @@ main(int argc, char *argv[]) else c = compile(argv[0], defs, ndef); + Bflush(&bstdout); if(c) errorexit(); exits(0); @@ -331,6 +354,7 @@ compile(char *file, char **defs, int ndef) void errorexit(void) { + Bflush(&bstdout); if(outfile) remove(outfile); exits("error"); @@ -390,7 +414,7 @@ newfile(char *s, int f) errorexit(); } fi.c = 0; - linehist(s, 0); + linklinehist(ctxt, lineno, s, 0); } Sym* @@ -1300,13 +1324,6 @@ cinit(void) nodproto = new(OPROTO, Z, Z); dclstack = D; - pathname = allocn(pathname, 0, 100); - if(getwd(pathname, 99) == 0) { - pathname = allocn(pathname, 100, 900); - if(getwd(pathname, 999) == 0) - strcpy(pathname, "/???"); - } - fmtinstall('O', Oconv); fmtinstall('T', Tconv); fmtinstall('F', FNconv); @@ -1314,6 +1331,7 @@ cinit(void) fmtinstall('Q', Qconv); fmtinstall('|', VBconv); fmtinstall('U', Uconv); + fmtinstall('B', Bconv); } int @@ -1330,7 +1348,7 @@ loop: fi.c = read(i->f, i->b, BUFSIZ) - 1; if(fi.c < 0) { close(i->f); - linehist(0, 0); + linklinehist(ctxt, lineno, nil, 0); goto pop; } fi.p = i->b + 1; @@ -1365,70 +1383,7 @@ Oconv(Fmt *fp) int Lconv(Fmt *fp) { - char str[STRINGSZ], s[STRINGSZ]; - Hist *h; - struct - { - Hist* incl; /* start of this include file */ - int32 idel; /* delta line number to apply to include */ - Hist* line; /* start of this #line directive */ - int32 ldel; /* delta line number to apply to #line */ - } a[HISTSZ]; - int32 l, d; - int i, n; - - l = va_arg(fp->args, int32); - n = 0; - for(h = hist; h != H; h = h->link) { - if(l < h->line) - break; - if(h->name) { - if(h->offset != 0) { /* #line directive, not #pragma */ - if(n > 0 && n < HISTSZ && h->offset >= 0) { - a[n-1].line = h; - a[n-1].ldel = h->line - h->offset + 1; - } - } else { - if(n < HISTSZ) { /* beginning of file */ - a[n].incl = h; - a[n].idel = h->line; - a[n].line = 0; - } - n++; - } - continue; - } - n--; - if(n > 0 && n < HISTSZ) { - d = h->line - a[n].incl->line; - a[n-1].ldel += d; - a[n-1].idel += d; - } - } - if(n > HISTSZ) - n = HISTSZ; - str[0] = 0; - for(i=n-1; i>=0; i--) { - if(i != n-1) { - if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */ - break; - strcat(str, " "); - } - if(a[i].line) - snprint(s, STRINGSZ, "%s:%d[%s:%d]", - a[i].line->name, l-a[i].ldel+1, - a[i].incl->name, l-a[i].idel+1); - else - snprint(s, STRINGSZ, "%s:%d", - a[i].incl->name, l-a[i].idel+1); - if(strlen(s)+strlen(str) >= STRINGSZ-10) - break; - strcat(str, s); - l = a[i].incl->line - 1; /* now print out start of this file */ - } - if(n == 0) - strcat(str, "<eof>"); - return fmtstrcpy(fp, str); + return linklinefmt(ctxt, fp); } int @@ -1548,6 +1503,32 @@ VBconv(Fmt *fp) return fmtstrcpy(fp, str); } +int +Bconv(Fmt *fp) +{ + char str[STRINGSZ], ss[STRINGSZ], *s; + Bits bits; + int i; + + str[0] = 0; + bits = va_arg(fp->args, Bits); + while(bany(&bits)) { + i = bnum(bits); + if(str[0]) + strcat(str, " "); + if(var[i].sym == nil) { + sprint(ss, "$%lld", var[i].offset); + s = ss; + } else + s = var[i].sym->name; + if(strlen(str) + strlen(s) + 1 >= STRINGSZ) + break; + strcat(str, s); + bits.b[i/32] &= ~(1L << (i%32)); + } + return fmtstrcpy(fp, str); +} + void setinclude(char *p) { diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody index 9d293b089..e24db1bc0 100644 --- a/src/cmd/cc/lexbody +++ b/src/cmd/cc/lexbody @@ -152,7 +152,7 @@ setinclude(char *p) void errorexit(void) { - + Bflush(&bstdout); if(outfile) remove(outfile); exits("error"); @@ -209,7 +209,7 @@ newfile(char *s, int f) errorexit(); } fi.c = 0; - linehist(s, 0); + linklinehist(ctxt, lineno, s, 0); } Sym* @@ -477,7 +477,7 @@ l1: return LCONST; case '"': - memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval)); + memcpy(yylval.sval, nullgen.u.sval, sizeof(yylval.sval)); cp = yylval.sval; c1 = 0; for(;;) { @@ -638,10 +638,6 @@ pinit(char *f) 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; @@ -661,7 +657,7 @@ loop: fi.c = read(i->f, i->b, BUFSIZ) - 1; if(fi.c < 0) { close(i->f); - linehist(0, 0); + linklinehist(ctxt, lineno, 0, 0); goto pop; } fi.p = i->b + 1; @@ -709,67 +705,5 @@ yyerror(char *a, ...) void prfile(int32 l) { - int i, n; - Hist a[HISTSZ], *h; - int32 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; /* shouldn't 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 = (uint32)ieee->l << 16; - ieee->l |= (int32)(fr*f); + linkprfile(ctxt, l); } diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody index f0a507669..f6927b2f6 100644 --- a/src/cmd/cc/macbody +++ b/src/cmd/cc/macbody @@ -642,7 +642,7 @@ nn: c = strlen(symb) + 1; cp = alloc(c); memcpy(cp, symb, c); - linehist(cp, n); + linklinehist(ctxt, lineno, cp, n); return; bad: @@ -713,7 +713,6 @@ macprag(void) Sym *s; int c0, c; char *hp; - Hist *h; s = getsym(); @@ -779,18 +778,7 @@ praglib: hp = alloc(c); memcpy(hp, symb, c); - h = alloc(sizeof(Hist)); - h->name = hp; - h->line = lineno; - h->offset = -1; - h->link = H; - if(ehist == H) { - hist = h; - ehist = h; - return; - } - ehist->link = h; - ehist = h; + linklinehist(ctxt, lineno, hp, -1); return; bad: @@ -810,43 +798,3 @@ macend(void) return; } } - -void -linehist(char *f, int offset) -{ - Hist *h; - - /* - * overwrite the last #line directive if - * no alloc has happened since the last one - */ - if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0) - if(f && ehist->name && strcmp(f, ehist->name) == 0) { - ehist->line = lineno; - ehist->offset = offset; - return; - } - - if(debug['f']) - if(f) { - if(offset) - print("%4d: %s (#line %d)\n", lineno, f, offset); - else - print("%4d: %s\n", lineno, f); - } else - print("%4d: <pop>\n", lineno); - newflag = 0; - - h = alloc(sizeof(Hist)); - h->name = f; - h->line = lineno; - h->offset = offset; - h->link = H; - if(ehist == H) { - hist = h; - ehist = h; - return; - } - ehist->link = h; - ehist = h; -} diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c index b82872bc5..10bebc196 100644 --- a/src/cmd/cc/pgen.c +++ b/src/cmd/cc/pgen.c @@ -35,6 +35,26 @@ enum { BitsPerPointer = 2 }; static void dumpgcargs(Type *fn, Sym *sym); +static Sym* +makefuncdatasym(char *namefmt, int64 funcdatakind) +{ + Node nod; + Sym *sym; + static int32 nsym; + static char namebuf[40]; + + snprint(namebuf, sizeof(namebuf), namefmt, nsym++); + sym = slookup(namebuf); + sym->class = CSTATIC; + memset(&nod, 0, sizeof nod); + nod.op = ONAME; + nod.sym = sym; + nod.class = CSTATIC; + gins(AFUNCDATA, nodconst(funcdatakind), &nod); + linksym(sym)->type = SRODATA; + return sym; +} + int hasdotdotdot(void) { @@ -80,10 +100,10 @@ void codgen(Node *n, Node *nn) { Prog *sp; - Node *n1, nod, nod1, nod2; - Sym *gcsym, *gclocalssym; - static int ngcsym, ngclocalssym; - static char namebuf[40]; + Node *n1, nod, nod1; + Sym *gcargs; + Sym *gclocals; + int isvarargs; cursafe = 0; curarg = 0; @@ -109,25 +129,11 @@ codgen(Node *n, Node *nn) * generate funcdata symbol for this function. * data is filled in at the end of codgen(). */ - snprint(namebuf, sizeof namebuf, "gc·%d", ngcsym++); - gcsym = slookup(namebuf); - gcsym->class = CSTATIC; - - memset(&nod, 0, sizeof nod); - nod.op = ONAME; - nod.sym = gcsym; - nod.class = CSTATIC; - gins(AFUNCDATA, nodconst(FUNCDATA_GCArgs), &nod); - - snprint(namebuf, sizeof(namebuf), "gclocalssym·%d", ngclocalssym++); - gclocalssym = slookup(namebuf); - gclocalssym->class = CSTATIC; - - memset(&nod2, 0, sizeof(nod2)); - nod2.op = ONAME; - nod2.sym = gclocalssym; - nod2.class = CSTATIC; - gins(AFUNCDATA, nodconst(FUNCDATA_GCLocals), &nod2); + isvarargs = hasdotdotdot(); + gcargs = nil; + if(!isvarargs) + gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps); + gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps); /* * isolate first argument @@ -166,7 +172,8 @@ codgen(Node *n, Node *nn) maxargsafe = xround(maxargsafe, 8); sp->to.offset += maxargsafe; - dumpgcargs(thisfn, gcsym); + if(!isvarargs) + dumpgcargs(thisfn, gcargs); // TODO(rsc): "stkoff" is not right. It does not account for // the possibility of data stored in .safe variables. @@ -177,9 +184,9 @@ codgen(Node *n, Node *nn) // area its own section. // That said, we've been using stkoff for months // and nothing too terrible has happened. - gextern(gclocalssym, nodconst(-stkoff), 0, 4); // locals - gclocalssym->type = typ(0, T); - gclocalssym->type->width = 4; + gextern(gclocals, nodconst(-stkoff), 0, 4); // locals + gclocals->type = typ(0, T); + gclocals->type->width = 4; } void @@ -655,7 +662,9 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param) { Type *t1; int32 o; + int32 widthptr; + widthptr = ewidth[TIND]; switch(t->etype) { case TCHAR: case TUCHAR: @@ -670,14 +679,16 @@ walktype1(Type *t, int32 offset, Bvec *bv, int param) case TFLOAT: case TDOUBLE: // non-pointer types + for(o = 0; o < t->width; o++) + bvset(bv, ((offset + t->offset + o) / widthptr) * BitsPerPointer); // 1 = live scalar break; case TIND: pointer: // pointer types - if((offset + t->offset) % ewidth[TIND] != 0) + if((offset + t->offset) % widthptr != 0) yyerror("unaligned pointer"); - bvset(bv, ((offset + t->offset) / ewidth[TIND])*BitsPerPointer); + bvset(bv, ((offset + t->offset) / widthptr)*BitsPerPointer + 1); // 2 = live ptr break; case TARRAY: @@ -715,39 +726,39 @@ dumpgcargs(Type *fn, Sym *sym) int32 argbytes; int32 symoffset, argoffset; - if(hasdotdotdot()) { - // give up for C vararg functions. - // TODO: maybe make a map just for the args we do know? - gextern(sym, nodconst(0), 0, 4); // nptrs=0 - symoffset = 4; - } else { - argbytes = (argsize() + ewidth[TIND] - 1); - bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer); - argoffset = align(0, fn->link, Aarg0, nil); - if(argoffset > 0) { - // The C calling convention returns structs by - // copying them to a location pointed to by a - // hidden first argument. This first argument - // is a pointer. - if(argoffset != ewidth[TIND]) - yyerror("passbyptr arg not the right size"); - bvset(bv, 0); - } - for(t = fn->down; t != T; t = t->down) { - if(t->etype == TVOID) - continue; - argoffset = align(argoffset, t, Aarg1, nil); - walktype1(t, argoffset, bv, 1); - argoffset = align(argoffset, t, Aarg2, nil); - } - gextern(sym, nodconst(bv->n), 0, 4); - symoffset = 4; - for(i = 0; i < bv->n; i += 32) { - gextern(sym, nodconst(bv->b[i/32]), symoffset, 4); - symoffset += 4; - } - free(bv); + // Dump the length of the bitmap array. This value is always one for + // functions written in C. + symoffset = 0; + gextern(sym, nodconst(1), symoffset, 4); + symoffset += 4; + argbytes = (argsize() + ewidth[TIND] - 1); + bv = bvalloc((argbytes / ewidth[TIND]) * BitsPerPointer); + argoffset = align(0, fn->link, Aarg0, nil); + if(argoffset > 0) { + // The C calling convention returns structs by copying them to a + // location pointed to by a hidden first argument. This first + // argument is a pointer. + if(argoffset != ewidth[TIND]) + yyerror("passbyptr arg not the right size"); + bvset(bv, 1); // 2 = live ptr + } + for(t = fn->down; t != T; t = t->down) { + if(t->etype == TVOID) + continue; + argoffset = align(argoffset, t, Aarg1, nil); + walktype1(t, argoffset, bv, 1); + argoffset = align(argoffset, t, Aarg2, nil); + } + // Dump the length of the bitmap. + gextern(sym, nodconst(bv->n), symoffset, 4); + symoffset += 4; + // Dump the words of the bitmap. + for(i = 0; i < bv->n; i += 32) { + gextern(sym, nodconst(bv->b[i/32]), symoffset, 4); + symoffset += 4; } + free(bv); + // Finalize the gc symbol. sym->type = typ(0, T); sym->type->width = symoffset; } diff --git a/src/cmd/cc/pswt.c b/src/cmd/cc/pswt.c index cc9c22763..bae57c64d 100644 --- a/src/cmd/cc/pswt.c +++ b/src/cmd/cc/pswt.c @@ -138,32 +138,3 @@ nullwarn(Node *l, Node *r) if(r != Z) cgen(r, Z); } - -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; /* shouldn't 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 |= (int32)(fr*f); -} diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c index bed989102..94c11d021 100644 --- a/src/cmd/cc/sub.c +++ b/src/cmd/cc/sub.c @@ -2056,3 +2056,13 @@ mixedasop(Type *l, Type *r) { return !typefd[l->etype] && typefd[r->etype]; } + +LSym* +linksym(Sym *s) +{ + if(s == nil) + return nil; + if(s->lsym != nil) + return s->lsym; + return linklookup(ctxt, s->name, s->class == CSTATIC); +} |