mirror of
https://github.com/golang/go
synced 2024-11-18 12:34:42 -07:00
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
This commit is contained in:
parent
6e37bc1eec
commit
b3defa2e8e
@ -31,8 +31,6 @@
|
|||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#include "../../pkg/runtime/funcdata.h"
|
#include "../../pkg/runtime/funcdata.h"
|
||||||
|
|
||||||
static int32 pointermap(Sym *gcsym, int32 offset);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
hasdotdotdot(void)
|
hasdotdotdot(void)
|
||||||
{
|
{
|
||||||
@ -103,22 +101,7 @@ codgen(Node *n, Node *nn)
|
|||||||
|
|
||||||
p = gtext(n1->sym, stkoff);
|
p = gtext(n1->sym, stkoff);
|
||||||
sp = p;
|
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
|
* isolate first argument
|
||||||
*/
|
*/
|
||||||
@ -156,6 +139,17 @@ codgen(Node *n, Node *nn)
|
|||||||
maxargsafe = xround(maxargsafe, 8);
|
maxargsafe = xround(maxargsafe, 8);
|
||||||
sp->to.offset += maxargsafe;
|
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
|
// TODO(rsc): "stkoff" is not right. It does not account for
|
||||||
// the possibility of data stored in .safe variables.
|
// the possibility of data stored in .safe variables.
|
||||||
// Unfortunately those move up and down just like
|
// Unfortunately those move up and down just like
|
||||||
@ -168,7 +162,8 @@ codgen(Node *n, Node *nn)
|
|||||||
off = 0;
|
off = 0;
|
||||||
gextern(gcsym, nodconst(stkoff), off, 4); // locals
|
gextern(gcsym, nodconst(stkoff), off, 4); // locals
|
||||||
off += 4;
|
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 = typ(0, T);
|
||||||
gcsym->type->width = off;
|
gcsym->type->width = off;
|
||||||
}
|
}
|
||||||
@ -638,105 +633,3 @@ bcomplex(Node *n, Node *c)
|
|||||||
boolgen(n, 1, Z);
|
boolgen(n, 1, Z);
|
||||||
return 0;
|
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
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user