From: Keith Randall Date: Wed, 24 Jul 2013 22:04:10 +0000 (-0700) Subject: undo CL 11683043 / bb75d03e6ccb X-Git-Tag: go1.2rc2~950 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b3defa2e8e66f5a03ce4ac344b9e5bcf3b4321d3;p=gostls13.git undo CL 11683043 / bb75d03e6ccb Broke arm build. R=dave ««« original CL description cc: generate argument pointer maps for C functions. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/11683043 »»» R=golang-dev CC=golang-dev https://golang.org/cl/11788043 --- diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c index 65a6cbea3e..27022d54e8 100644 --- a/src/cmd/cc/pgen.c +++ b/src/cmd/cc/pgen.c @@ -31,8 +31,6 @@ #include "gc.h" #include "../../pkg/runtime/funcdata.h" -static int32 pointermap(Sym *gcsym, int32 offset); - int hasdotdotdot(void) { @@ -103,22 +101,7 @@ codgen(Node *n, Node *nn) p = gtext(n1->sym, stkoff); sp = p; - - /* - * 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_GC), &nod); - + /* * isolate first argument */ @@ -156,6 +139,17 @@ codgen(Node *n, Node *nn) maxargsafe = xround(maxargsafe, 8); sp->to.offset += maxargsafe; + 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_GC), &nod); + // TODO(rsc): "stkoff" is not right. It does not account for // the possibility of data stored in .safe variables. // Unfortunately those move up and down just like @@ -168,7 +162,8 @@ codgen(Node *n, Node *nn) off = 0; gextern(gcsym, nodconst(stkoff), off, 4); // locals off += 4; - off = pointermap(gcsym, off); // nptrs and ptrs[...] + gextern(gcsym, nodconst(0), off, 4); // nptrs + off += 4; gcsym->type = typ(0, T); gcsym->type->width = off; } @@ -638,105 +633,3 @@ bcomplex(Node *n, Node *c) boolgen(n, 1, Z); return 0; } - -// Makes a bitmap marking the the pointers in t. t starts at the given byte -// offset in the argument list. The returned bitmap should be for pointer -// indexes (relative to offset 0) between baseidx and baseidx+32. -static int32 -pointermap_type(Type *t, int32 offset, int32 baseidx) -{ - Type *t1; - int32 idx; - int32 m; - - switch(t->etype) { - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TVLONG: - case TUVLONG: - case TFLOAT: - case TDOUBLE: - // non-pointer types - return 0; - case TIND: - case TARRAY: // unlike Go, C passes arrays by reference - // pointer types - if((offset + t->offset) % ewidth[TIND] != 0) - yyerror("unaligned pointer"); - idx = (offset + t->offset) / ewidth[TIND]; - if(idx >= baseidx && idx < baseidx + 32) - return 1 << (idx - baseidx); - return 0; - case TSTRUCT: - // build map recursively - m = 0; - for(t1=t->link; t1; t1=t1->down) - m |= pointermap_type(t1, offset, baseidx); - return m; - case TUNION: - // We require that all elements of the union have the same pointer map. - m = pointermap_type(t->link, offset, baseidx); - for(t1=t->link->down; t1; t1=t1->down) { - if(pointermap_type(t1, offset, baseidx) != m) - yyerror("invalid union in argument list - pointer maps differ"); - } - return m; - default: - yyerror("can't handle arg type %s\n", tnames[t->etype]); - return 0; - } -} - -// Compute a bit vector to describe the pointer containing locations -// in the argument list. Adds the data to gcsym and returns the offset -// of end of the bit vector. -static int32 -pointermap(Sym *gcsym, int32 off) -{ - int32 nptrs; - int32 i; - int32 s; // offset in argument list (in bytes) - int32 m; // current ptrs[i/32] - Type *t; - - if(hasdotdotdot()) { - // give up for C vararg functions. - // TODO: maybe make a map just for the args we do know? - gextern(gcsym, nodconst(0), off, 4); // nptrs=0 - return off + 4; - } - nptrs = (argsize() + ewidth[TIND] - 1) / ewidth[TIND]; - gextern(gcsym, nodconst(nptrs), off, 4); - off += 4; - - for(i = 0; i < nptrs; i += 32) { - // generate mask for ptrs at offsets i ... i+31 - m = 0; - s = align(0, thisfn->link, Aarg0, nil); - if(s > 0 && i == 0) { - // 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(s != ewidth[TIND]) - yyerror("passbyptr arg not the right size"); - m = 1; - } - for(t=thisfn->down; t!=T; t=t->down) { - if(t->etype == TVOID) - continue; - s = align(s, t, Aarg1, nil); - m |= pointermap_type(t, s, i); - s = align(s, t, Aarg2, nil); - } - gextern(gcsym, nodconst(m), off, 4); - off += 4; - } - return off; - // TODO: needs a test for nptrs>32 -}