1
0
mirror of https://github.com/golang/go synced 2024-11-26 17:46:57 -07:00
[]ptr bug
proc reuses old g* structures
differnt assignment of offsets to parameters

SVN=127888
This commit is contained in:
Ken Thompson 2008-07-17 15:03:39 -07:00
parent d88c759e87
commit 9e2d185040
5 changed files with 78 additions and 109 deletions

View File

@ -92,58 +92,6 @@ allocparams(void)
Node *n; Node *n;
ulong w; ulong w;
/*
* allocate (set xoffset) the stack
* slots for this, inargs, outargs
* these are allocated positavely
* from 0 up.
* note that this uses the 'width'
* field, which, in the OFIELD of the
* parameters, is the offset in the
* parameter list.
*/
d = curfn->type->param->forw;
t = funcfirst(&list, curfn->type);
while(t != T) {
if(d == D)
fatal("allocparams: this & in nil");
if(d->op != ONAME) {
d = d->forw;
continue;
}
n = d->dnode;
if(n->class != PPARAM)
fatal("allocparams: this & in class %N %d", n, n->class);
//print("assign %S %ld\n", n->sym, t->width);
n->xoffset = t->width;
d = d->forw;
t = funcnext(&list);
}
t = structfirst(&list, getoutarg(curfn->type));
while(t != T) {
if(t->nname != N && t->nname->sym->name[0] != '_') {
if(d == D)
fatal("allocparams: out nil");
if(d->op != ONAME) {
d = d->forw;
continue;
}
n = d->dnode;
if(n->class != PPARAM)
fatal("allocparams: out class %N %d", n, n->class);
n->xoffset = t->width;
d = d->forw;
}
t = structnext(&list);
}
/* /*
* allocate (set xoffset) the stack * allocate (set xoffset) the stack
* slots for all automatics. * slots for all automatics.
@ -996,56 +944,16 @@ samereg(Node *a, Node *b)
return 1; return 1;
} }
/*
* this is hard because divide
* is done in a fixed numerator
* of combined DX:AX registers
*/
void void
cgen_div(int op, Node *nl, Node *nr, Node *res) dodiv(int op, Node *nl, Node *nr, Node *res)
{ {
int a;
Node n1, n2, n3; Node n1, n2, n3;
int a, rax, rdx;
rax = reg[D_AX];
rdx = reg[D_DX];
nodreg(&n1, types[TINT64], D_AX); nodreg(&n1, types[TINT64], D_AX);
nodreg(&n2, types[TINT64], D_DX); nodreg(&n2, types[TINT64], D_DX);
regalloc(&n1, nr->type, &n1); regalloc(&n1, nl->type, &n1);
regalloc(&n2, nr->type, &n2); regalloc(&n2, nl->type, &n2);
// clean out the AX register
if(rax && !samereg(res, &n1)) {
regalloc(&n3, types[TINT64], N);
gins(AMOVQ, &n1, &n3);
regfree(&n1);
regfree(&n2);
reg[D_AX] = 0;
cgen_div(op, nl, nr, res);
reg[D_AX] = rax;
gins(AMOVQ, &n3, &n1);
regfree(&n3);
goto ret;
}
// clean out the DX register
if(rdx && !samereg(res, &n2)) {
regalloc(&n3, types[TINT64], N);
gins(AMOVQ, &n2, &n3);
regfree(&n1);
regfree(&n2);
reg[D_DX] = 0;
cgen_div(op, nl, nr, res);
reg[D_DX] = rdx;
gins(AMOVQ, &n3, &n2);
regfree(&n3);
goto ret;
}
a = optoas(op, nl->type); a = optoas(op, nl->type);
@ -1077,9 +985,72 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
regfree(&n1); regfree(&n1);
regfree(&n2); regfree(&n2);
}
ret: /*
; * this is hard because divide
* is done in a fixed numerator
* of combined DX:AX registers
*/
void
cgen_div(int op, Node *nl, Node *nr, Node *res)
{
Node n1, n2, n3, n4, n5;
int a, rax, rdx;
rax = reg[D_AX];
rdx = reg[D_DX];
nodreg(&n1, types[TINT64], D_AX);
nodreg(&n2, types[TINT64], D_DX);
// clean out the AX register
if(rax && !samereg(res, &n1)) {
if(rdx && !samereg(res, &n2)) {
regalloc(&n5, types[TINT64], N); // DX holder
regalloc(&n4, types[TINT64], N); // AX holder
regalloc(&n3, nl->type, N); // dest for div
gins(AMOVQ, &n2, &n5);
gins(AMOVQ, &n1, &n4);
dodiv(op, nl, nr, &n3);
gins(AMOVQ, &n4, &n1);
gins(AMOVQ, &n5, &n2);
gmove(&n3, res);
regfree(&n5);
regfree(&n4);
regfree(&n3);
return;
}
regalloc(&n4, types[TINT64], N); // AX holder
regalloc(&n3, nl->type, N); // dest for div
gins(AMOVQ, &n1, &n4);
dodiv(op, nl, nr, &n3);
gins(AMOVQ, &n4, &n1);
gmove(&n3, res);
regfree(&n4);
regfree(&n3);
return;
}
// clean out the DX register
if(rdx && !samereg(res, &n2)) {
regalloc(&n4, types[TINT64], N); // DX holder
regalloc(&n3, nl->type, N); // dest for div
gins(AMOVQ, &n2, &n4);
dodiv(op, nl, nr, &n3);
gins(AMOVQ, &n4, &n2);
gmove(&n3, res);
regfree(&n4);
regfree(&n3);
return;
}
dodiv(op, nl, nr, res);
} }
/* /*

View File

@ -370,13 +370,13 @@ funcargs(Type *ft)
Iter save; Iter save;
int all; int all;
ft->param = autodcl->back; // base of arguments - see allocparams in gen.c
// declare the this/in arguments // declare the this/in arguments
t = funcfirst(&save, ft); t = funcfirst(&save, ft);
while(t != T) { while(t != T) {
if(t->nname != N) if(t->nname != N) {
t->nname->xoffset = t->width;
addvar(t->nname, t->type, PPARAM); addvar(t->nname, t->type, PPARAM);
}
t = funcnext(&save); t = funcnext(&save);
} }
@ -384,6 +384,8 @@ funcargs(Type *ft)
all = 0; all = 0;
t = structfirst(&save, getoutarg(ft)); t = structfirst(&save, getoutarg(ft));
while(t != T) { while(t != T) {
if(t->nname != N)
t->nname->xoffset = t->width;
if(t->nname != N && t->nname->sym->name[0] != '_') { if(t->nname != N && t->nname->sym->name[0] != '_') {
addvar(t->nname, t->type, PPARAM); addvar(t->nname, t->type, PPARAM);
all |= 1; all |= 1;

View File

@ -68,7 +68,6 @@ struct Val
typedef struct Sym Sym; typedef struct Sym Sym;
typedef struct Node Node; typedef struct Node Node;
typedef struct Type Type; typedef struct Type Type;
typedef struct Dcl Dcl;
struct Type struct Type
{ {
@ -85,7 +84,6 @@ struct Type
Sym* sym; Sym* sym;
long vargen; // unique name for OTYPE/ONAME long vargen; // unique name for OTYPE/ONAME
Dcl* param;
// most nodes // most nodes
Type* type; Type* type;
@ -175,6 +173,7 @@ struct Sym
}; };
#define S ((Sym*)0) #define S ((Sym*)0)
typedef struct Dcl Dcl;
struct Dcl struct Dcl
{ {
uchar op; uchar op;

View File

@ -1506,6 +1506,7 @@ ptrto(Type *t)
fatal("ptrto: nil"); fatal("ptrto: nil");
t1 = typ(tptr); t1 = typ(tptr);
t1->type = t; t1->type = t;
t1->width = types[tptr]->width;
return t1; return t1;
} }

View File

@ -28,12 +28,8 @@ sys·newproc(int32 siz, byte* fn, byte* arg0)
//sys·printpointer(fn); //sys·printpointer(fn);
siz = (siz+7) & ~7; siz = (siz+7) & ~7;
if(siz > 1024) { if(siz > 1024)
prints("sys·newproc: too many args: "); throw("sys·newproc: too many args");
sys·printint(siz);
prints("\n");
sys·panicl(123);
}
// try to rip off an old goroutine // try to rip off an old goroutine
for(newg=allg; newg!=nil; newg=newg->alllink) for(newg=allg; newg!=nil; newg=newg->alllink)