Commit 5ecd010b authored by Russ Cox's avatar Russ Cox

more 8g.

test/turing.go runs if you move the big array off its stack.

finally remembered to g4 add cgen.c gsubr.c

R=ken
OCL=29408
CL=29408
parent 70d711df
This diff is collapsed.
...@@ -85,6 +85,7 @@ void ginscall(Node*, int); ...@@ -85,6 +85,7 @@ void ginscall(Node*, int);
* cgen * cgen
*/ */
void agen(Node*, Node*); void agen(Node*, Node*);
void agenr(Node *n, Node *a, Node *res);
void igen(Node*, Node*, Node*); void igen(Node*, Node*, Node*);
vlong fieldoffset(Type*, Node*); vlong fieldoffset(Type*, Node*);
void bgen(Node*, int, Prog*); void bgen(Node*, int, Prog*);
...@@ -129,7 +130,7 @@ void buildtxt(void); ...@@ -129,7 +130,7 @@ void buildtxt(void);
Plist* newplist(void); Plist* newplist(void);
int isfat(Type*); int isfat(Type*);
void sudoclean(void); void sudoclean(void);
int sudoaddable(Node*, Addr*); int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*); void afunclit(Addr*);
/* /*
......
...@@ -99,7 +99,40 @@ ret: ...@@ -99,7 +99,40 @@ ret:
void void
clearfat(Node *nl) clearfat(Node *nl)
{ {
fatal("clearfat"); uint32 w, c, q;
Node n1;
/* clear a fat object */
if(debug['g'])
dump("\nclearfat", nl);
w = nl->type->width;
c = w % 4; // bytes
q = w / 4; // quads
gconreg(AMOVL, 0, D_AX);
nodreg(&n1, types[tptr], D_DI);
agen(nl, &n1);
if(q >= 4) {
gconreg(AMOVL, q, D_CX);
gins(AREP, N, N); // repeat
gins(ASTOSL, N, N); // STOL AL,*(DI)+
} else
while(q > 0) {
gins(ASTOSL, N, N); // STOL AL,*(DI)+
q--;
}
if(c >= 4) {
gconreg(AMOVL, c, D_CX);
gins(AREP, N, N); // repeat
gins(ASTOSB, N, N); // STOB AL,*(DI)+
} else
while(c > 0) {
gins(ASTOSB, N, N); // STOB AL,*(DI)+
c--;
}
} }
/* /*
...@@ -290,7 +323,127 @@ cgen_ret(Node *n) ...@@ -290,7 +323,127 @@ cgen_ret(Node *n)
void void
cgen_asop(Node *n) cgen_asop(Node *n)
{ {
fatal("cgen_asop"); Node n1, n2, n3, n4;
Node *nl, *nr;
Prog *p1;
Addr addr;
int a;
nl = n->left;
nr = n->right;
if(nr->ullman >= UINF && nl->ullman >= UINF) {
tempname(&n1, nr->type);
cgen(nr, &n1);
n2 = *n;
n2.right = &n1;
cgen_asop(&n2);
goto ret;
}
if(!isint[nl->type->etype])
goto hard;
if(!isint[nr->type->etype])
goto hard;
switch(n->etype) {
case OADD:
if(smallintconst(nr))
if(mpgetfix(nr->val.u.xval) == 1) {
a = optoas(OINC, nl->type);
if(nl->addable) {
gins(a, N, nl);
goto ret;
}
if(sudoaddable(a, nl, &addr)) {
p1 = gins(a, N, N);
p1->to = addr;
sudoclean();
goto ret;
}
}
break;
case OSUB:
if(smallintconst(nr))
if(mpgetfix(nr->val.u.xval) == 1) {
a = optoas(ODEC, nl->type);
if(nl->addable) {
gins(a, N, nl);
goto ret;
}
if(sudoaddable(a, nl, &addr)) {
p1 = gins(a, N, N);
p1->to = addr;
sudoclean();
goto ret;
}
}
break;
}
switch(n->etype) {
case OADD:
case OSUB:
case OXOR:
case OAND:
case OOR:
a = optoas(n->etype, nl->type);
if(nl->addable) {
if(smallintconst(nr)) {
gins(a, nr, nl);
goto ret;
}
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
gins(a, &n2, nl);
regfree(&n2);
goto ret;
}
if(nr->ullman < UINF)
if(sudoaddable(a, nl, &addr)) {
if(smallintconst(nr)) {
p1 = gins(a, nr, N);
p1->to = addr;
sudoclean();
goto ret;
}
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
p1 = gins(a, &n2, N);
p1->to = addr;
regfree(&n2);
sudoclean();
goto ret;
}
}
hard:
if(nr->ullman > nl->ullman) {
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
igen(nl, &n1, N);
} else {
igen(nl, &n1, N);
tempalloc(&n2, nr->type);
cgen(nr, &n2);
}
n3 = *n;
n3.left = &n1;
n3.right = &n2;
n3.op = n->etype;
tempalloc(&n4, nl->type);
cgen(&n3, &n4);
gmove(&n4, &n1);
regfree(&n1);
tempfree(&n4);
tempfree(&n2);
ret:
;
} }
/* /*
......
This diff is collapsed.
...@@ -82,7 +82,7 @@ Dconv(Fmt *fp) ...@@ -82,7 +82,7 @@ Dconv(Fmt *fp)
i = a->type; i = a->type;
if(i >= D_INDIR) { if(i >= D_INDIR) {
if(a->offset) if(a->offset)
snprint(str, sizeof(str), "%ld(%R)", a->offset, i-D_INDIR); snprint(str, sizeof(str), "%d(%R)", a->offset, i-D_INDIR);
else else
snprint(str, sizeof(str), "(%R)", i-D_INDIR); snprint(str, sizeof(str), "(%R)", i-D_INDIR);
goto brk; goto brk;
...@@ -91,7 +91,7 @@ Dconv(Fmt *fp) ...@@ -91,7 +91,7 @@ Dconv(Fmt *fp)
default: default:
if(a->offset) if(a->offset)
snprint(str, sizeof(str), "$%ld,%R", a->offset, i); snprint(str, sizeof(str), "$%d,%R", a->offset, i);
else else
snprint(str, sizeof(str), "%R", i); snprint(str, sizeof(str), "%R", i);
break; break;
...@@ -101,33 +101,33 @@ Dconv(Fmt *fp) ...@@ -101,33 +101,33 @@ Dconv(Fmt *fp)
break; break;
case D_BRANCH: case D_BRANCH:
snprint(str, sizeof(str), "%ld", a->branch->loc); snprint(str, sizeof(str), "%d", a->branch->loc);
break; break;
case D_EXTERN: case D_EXTERN:
snprint(str, sizeof(str), "%S+%ld(SB)", a->sym, a->offset); snprint(str, sizeof(str), "%S+%d(SB)", a->sym, a->offset);
break; break;
case D_STATIC: case D_STATIC:
snprint(str, sizeof(str), "%S<>+%ld(SB)", a->sym, a->offset); snprint(str, sizeof(str), "%S<>+%d(SB)", a->sym, a->offset);
break; break;
case D_AUTO: case D_AUTO:
snprint(str, sizeof(str), "%S+%ld(SP)", a->sym, a->offset); snprint(str, sizeof(str), "%S+%d(SP)", a->sym, a->offset);
break; break;
case D_PARAM: case D_PARAM:
snprint(str, sizeof(str), "%S+%ld(FP)", a->sym, a->offset); snprint(str, sizeof(str), "%S+%d(FP)", a->sym, a->offset);
break; break;
case D_CONST: case D_CONST:
if(fp->flags & FmtLong) { if(fp->flags & FmtLong) {
d1 = a->offset; d1 = a->offset;
d2 = a->offset2; d2 = a->offset2;
snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2); snprint(str, sizeof(str), "$%ud-%ud", (ulong)d1, (ulong)d2);
break; break;
} }
snprint(str, sizeof(str), "$%ld", a->offset); snprint(str, sizeof(str), "$%d", a->offset);
break; break;
case D_FCONST: case D_FCONST:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment