Commit 8d76a151 authored by Kai Backman's avatar Kai Backman

arm: bugfixes (stack clobbering, indices)

also changed zerodivide to output "BUG"

R=rsc
CC=golang-dev
https://golang.org/cl/1871055
parent 96ad9ade
...@@ -4,33 +4,6 @@ ...@@ -4,33 +4,6 @@
#include "gg.h" #include "gg.h"
void
mgen(Node *n, Node *n1, Node *rg)
{
n1->ostk = 0;
n1->op = OEMPTY;
if(n->addable) {
*n1 = *n;
n1->ostk = 0;
if(n1->op == OREGISTER || n1->op == OINDREG)
reg[n->val.u.reg]++;
return;
}
if(n->type->width > widthptr)
tempname(n1, n->type);
else
regalloc(n1, n->type, rg);
cgen(n, n1);
}
void
mfree(Node *n)
{
if(n->op == OREGISTER)
regfree(n);
}
/* /*
* generate: * generate:
* res = n; * res = n;
...@@ -269,10 +242,26 @@ cgen(Node *n, Node *res) ...@@ -269,10 +242,26 @@ cgen(Node *n, Node *res)
cgen(nl, res); cgen(nl, res);
break; break;
} }
if(nl->addable && !is64(nl->type)) {
mgen(nl, &n1, res); regalloc(&n1, nl->type, res);
gmove(&n1, res); gmove(nl, &n1);
mfree(&n1); } else {
if(n->type->width > widthptr || is64(nl->type) || isfloat[nl->type->etype])
tempname(&n1, nl->type);
else
regalloc(&n1, nl->type, res);
cgen(nl, &n1);
}
if(n->type->width > widthptr || is64(n->type) || isfloat[n->type->etype])
tempname(&n2, n->type);
else
regalloc(&n2, n->type, N);
gmove(&n1, &n2);
gmove(&n2, res);
if(n1.op == OREGISTER)
regfree(&n1);
if(n2.op == OREGISTER)
regfree(&n2);
break; break;
case ODOT: case ODOT:
...@@ -460,6 +449,41 @@ ret: ...@@ -460,6 +449,41 @@ ret:
; ;
} }
/*
* generate array index into res.
* n might be any size; res is 32-bit.
* returns Prog* to patch to panic call.
*/
Prog*
cgenindex(Node *n, Node *res)
{
Node tmp, lo, hi, zero, n1, n2;
if(!is64(n->type)) {
cgen(n, res);
return nil;
}
tempname(&tmp, types[TINT64]);
cgen(n, &tmp);
split64(&tmp, &lo, &hi);
gmove(&lo, res);
if(debug['B']) {
splitclean();
return nil;
}
regalloc(&n1, types[TINT32], N);
regalloc(&n2, types[TINT32], N);
nodconst(&zero, types[TINT32], 0);
gmove(&hi, &n1);
gmove(&zero, &n2);
gcmp(ACMP, &n1, &n2);
regfree(&n2);
regfree(&n1);
splitclean();
return gbranch(ABNE, T);
}
/* /*
* generate: * generate:
* res = &n; * res = &n;
...@@ -469,10 +493,9 @@ agen(Node *n, Node *res) ...@@ -469,10 +493,9 @@ agen(Node *n, Node *res)
{ {
Node *nl, *nr; Node *nl, *nr;
Node n1, n2, n3, n4, n5, tmp; Node n1, n2, n3, n4, n5, tmp;
Prog *p1; Prog *p1, *p2;
uint32 w; uint32 w;
uint64 v; uint64 v;
Type *t;
if(debug['g']) { if(debug['g']) {
dump("\nagen-res", res); dump("\nagen-res", res);
...@@ -519,20 +542,20 @@ agen(Node *n, Node *res) ...@@ -519,20 +542,20 @@ agen(Node *n, Node *res)
break; break;
case OINDEX: case OINDEX:
// TODO(rsc): uint64 indices p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
if(nr->addable) { if(nr->addable) {
agenr(nl, &n3, res); agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
cgen(nr, &tmp); p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
} else if(nl->addable) { } else if(nl->addable) {
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
cgen(nr, &tmp); p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
...@@ -540,7 +563,7 @@ agen(Node *n, Node *res) ...@@ -540,7 +563,7 @@ agen(Node *n, Node *res)
agen(nl, &n3); agen(nl, &n3);
} else { } else {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
cgen(nr, &tmp); p2 = cgenindex(nr, &tmp);
nr = &tmp; nr = &tmp;
agenr(nl, &n3, res); agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
...@@ -602,12 +625,7 @@ agen(Node *n, Node *res) ...@@ -602,12 +625,7 @@ agen(Node *n, Node *res)
break; break;
} }
// type of the index regalloc(&n2, types[TINT32], &n1); // i
t = types[TUINT32];
if(issigned[n1.type->etype])
t = types[TINT32];
regalloc(&n2, t, &n1); // i
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
...@@ -627,6 +645,8 @@ agen(Node *n, Node *res) ...@@ -627,6 +645,8 @@ agen(Node *n, Node *res)
gcmp(optoas(OCMP, types[TUINT32]), &n2, &n4); gcmp(optoas(OCMP, types[TUINT32]), &n2, &n4);
regfree(&n4); regfree(&n4);
p1 = gbranch(optoas(OLT, types[TUINT32]), T); p1 = gbranch(optoas(OLT, types[TUINT32]), T);
if(p2)
patch(p2, pc);
ginscall(panicindex, 0); ginscall(panicindex, 0);
patch(p1, pc); patch(p1, pc);
} }
...@@ -653,10 +673,10 @@ agen(Node *n, Node *res) ...@@ -653,10 +673,10 @@ agen(Node *n, Node *res)
else if(w == 8) else if(w == 8)
gshift(AADD, &n2, SHIFT_LL, 3, &n3); gshift(AADD, &n2, SHIFT_LL, 3, &n3);
} else { } else {
regalloc(&n4, t, N); regalloc(&n4, types[TUINT32], N);
nodconst(&n1, t, w); nodconst(&n1, types[TUINT32], w);
gmove(&n1, &n4); gmove(&n1, &n4);
gins(optoas(OMUL, t), &n4, &n2); gins(optoas(OMUL, types[TUINT32]), &n4, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OADD, types[tptr]), &n2, &n3);
regfree(&n4); regfree(&n4);
gmove(&n3, res); gmove(&n3, res);
...@@ -1088,7 +1108,7 @@ stkof(Node *n) ...@@ -1088,7 +1108,7 @@ stkof(Node *n)
t = structfirst(&flist, getoutarg(t)); t = structfirst(&flist, getoutarg(t));
if(t != T) if(t != T)
return t->width; return t->width + 4; // correct for LR
break; break;
} }
......
...@@ -90,6 +90,7 @@ void ginscall(Node*, int); ...@@ -90,6 +90,7 @@ void ginscall(Node*, int);
* cgen * cgen
*/ */
void agen(Node*, Node*); void agen(Node*, Node*);
Prog* cgenindex(Node *, Node *);
void igen(Node*, Node*, Node*); void igen(Node*, Node*, Node*);
void agenr(Node *n, Node *a, Node *res); void agenr(Node *n, Node *a, Node *res);
vlong fieldoffset(Type*, Node*); vlong fieldoffset(Type*, Node*);
......
...@@ -991,7 +991,7 @@ gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs) ...@@ -991,7 +991,7 @@ gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
{ {
Prog *p; Prog *p;
if (sval <= 0 || sval > 32) if(sval <= 0 || sval > 32)
fatal("bad shift value: %d", sval); fatal("bad shift value: %d", sval);
sval = sval&0x1f; sval = sval&0x1f;
...@@ -1054,7 +1054,7 @@ naddr(Node *n, Addr *a, int canemitcode) ...@@ -1054,7 +1054,7 @@ naddr(Node *n, Addr *a, int canemitcode)
break; break;
case OREGISTER: case OREGISTER:
if (n->val.u.reg <= REGALLOC_RMAX) { if(n->val.u.reg <= REGALLOC_RMAX) {
a->type = D_REG; a->type = D_REG;
a->reg = n->val.u.reg; a->reg = n->val.u.reg;
} else { } else {
...@@ -1594,7 +1594,7 @@ sudoaddable(int as, Node *n, Addr *a, int *w) ...@@ -1594,7 +1594,7 @@ sudoaddable(int as, Node *n, Addr *a, int *w)
int64 v; int64 v;
Node n1, n2, n3, n4, *nn, *l, *r; Node n1, n2, n3, n4, *nn, *l, *r;
Node *reg, *reg1; Node *reg, *reg1;
Prog *p1; Prog *p1, *p2;
Type *t; Type *t;
if(n->type == T) if(n->type == T)
...@@ -1732,8 +1732,8 @@ oindex: ...@@ -1732,8 +1732,8 @@ oindex:
if(issigned[r->type->etype]) if(issigned[r->type->etype])
t = types[TINT32]; t = types[TINT32];
regalloc(reg1, t, N); regalloc(reg1, t, N);
regalloc(&n3, r->type, reg1); regalloc(&n3, types[TINT32], reg1);
cgen(r, &n3); p2 = cgenindex(r, &n3);
gmove(&n3, reg1); gmove(&n3, reg1);
regfree(&n3); regfree(&n3);
...@@ -1774,6 +1774,8 @@ oindex: ...@@ -1774,6 +1774,8 @@ oindex:
gcmp(optoas(OCMP, types[TUINT32]), reg1, &n3); gcmp(optoas(OCMP, types[TUINT32]), reg1, &n3);
regfree(&n3); regfree(&n3);
p1 = gbranch(optoas(OLT, types[TUINT32]), T); p1 = gbranch(optoas(OLT, types[TUINT32]), T);
if(p2)
patch(p2, pc);
ginscall(panicindex, 0); ginscall(panicindex, 0);
patch(p1, pc); patch(p1, pc);
} }
...@@ -1786,7 +1788,7 @@ oindex: ...@@ -1786,7 +1788,7 @@ oindex:
gmove(&n2, reg); gmove(&n2, reg);
} }
if (*w == 1) if(*w == 1)
gins(AADD, reg1, reg); gins(AADD, reg1, reg);
else if(*w == 2) else if(*w == 2)
gshift(AADD, reg1, SHIFT_LL, 1, reg); gshift(AADD, reg1, SHIFT_LL, 1, reg);
......
./235.go ./235.go
# ./64bit.go # flaky # ./64bit.go # fail, flaky
./args.go ./args.go
./assign.go ./assign.go
./assign1.go ./assign1.go
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
./indirect.go ./indirect.go
./indirect1.go ./indirect1.go
./initcomma.go ./initcomma.go
# ./initialize.go # fail, BUG ./initialize.go
./initializerr.go ./initializerr.go
./initsyscall.go ./initsyscall.go
./int_lit.go ./int_lit.go
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
./varerr.go ./varerr.go
./varinit.go ./varinit.go
./vectors.go ./vectors.go
./zerodivide.go # ./zerodivide.go # fail, BUG
ken/array.go ken/array.go
ken/chan.go ken/chan.go
ken/chan1.go ken/chan1.go
...@@ -179,7 +179,7 @@ interface/embed0.go ...@@ -179,7 +179,7 @@ interface/embed0.go
interface/embed1.go interface/embed1.go
interface/explicit.go interface/explicit.go
interface/fail.go interface/fail.go
# interface/fake.go # fail interface/fake.go
interface/pointer.go interface/pointer.go
interface/receiver.go interface/receiver.go
interface/receiver1.go interface/receiver1.go
...@@ -408,7 +408,7 @@ fixedbugs/bug217.go ...@@ -408,7 +408,7 @@ fixedbugs/bug217.go
fixedbugs/bug218.go fixedbugs/bug218.go
fixedbugs/bug219.go fixedbugs/bug219.go
fixedbugs/bug220.go fixedbugs/bug220.go
# fixedbugs/bug221.go # fail fixedbugs/bug221.go
fixedbugs/bug222.go fixedbugs/bug222.go
fixedbugs/bug223.go fixedbugs/bug223.go
fixedbugs/bug224.go fixedbugs/bug224.go
...@@ -423,14 +423,14 @@ fixedbugs/bug232.go ...@@ -423,14 +423,14 @@ fixedbugs/bug232.go
fixedbugs/bug233.go fixedbugs/bug233.go
fixedbugs/bug234.go fixedbugs/bug234.go
fixedbugs/bug235.go fixedbugs/bug235.go
# fixedbugs/bug236.go # fail fixedbugs/bug236.go
fixedbugs/bug237.go fixedbugs/bug237.go
fixedbugs/bug238.go fixedbugs/bug238.go
fixedbugs/bug239.go fixedbugs/bug239.go
fixedbugs/bug240.go fixedbugs/bug240.go
fixedbugs/bug241.go fixedbugs/bug241.go
fixedbugs/bug242.go fixedbugs/bug242.go
# fixedbugs/bug243.go # fail fixedbugs/bug243.go
fixedbugs/bug244.go fixedbugs/bug244.go
fixedbugs/bug245.go fixedbugs/bug245.go
fixedbugs/bug246.go fixedbugs/bug246.go
...@@ -458,7 +458,7 @@ fixedbugs/bug268.go ...@@ -458,7 +458,7 @@ fixedbugs/bug268.go
fixedbugs/bug269.go fixedbugs/bug269.go
fixedbugs/bug270.go fixedbugs/bug270.go
fixedbugs/bug271.go fixedbugs/bug271.go
# fixedbugs/bug272.go # fail fixedbugs/bug272.go
fixedbugs/bug273.go fixedbugs/bug273.go
fixedbugs/bug274.go fixedbugs/bug274.go
fixedbugs/bug275.go fixedbugs/bug275.go
...@@ -467,7 +467,7 @@ fixedbugs/bug277.go ...@@ -467,7 +467,7 @@ fixedbugs/bug277.go
fixedbugs/bug278.go fixedbugs/bug278.go
fixedbugs/bug279.go fixedbugs/bug279.go
fixedbugs/bug280.go fixedbugs/bug280.go
# fixedbugs/bug281.go # fail, BUG fixedbugs/bug281.go
fixedbugs/bug282.go fixedbugs/bug282.go
fixedbugs/bug283.go fixedbugs/bug283.go
fixedbugs/bug284.go fixedbugs/bug284.go
......
...@@ -51,30 +51,6 @@ FAIL ...@@ -51,30 +51,6 @@ FAIL
=========== ./turing.go =========== ./turing.go
Hello World! Hello World!
=========== ./zerodivide.go
int 0/0: expected "divide"; got no error
int8 0/0: expected "divide"; got no error
int16 0/0: expected "divide"; got no error
int32 0/0: expected "divide"; got no error
int64 0/0: expected "divide"; got no error
int 1/0: expected "divide"; got no error
int8 1/0: expected "divide"; got no error
int16 1/0: expected "divide"; got no error
int32 1/0: expected "divide"; got no error
int64 1/0: expected "divide"; got no error
uint 0/0: expected "divide"; got no error
uint8 0/0: expected "divide"; got no error
uint16 0/0: expected "divide"; got no error
uint32 0/0: expected "divide"; got no error
uint64 0/0: expected "divide"; got no error
uintptr 0/0: expected "divide"; got no error
uint 1/0: expected "divide"; got no error
uint8 1/0: expected "divide"; got no error
uint16 1/0: expected "divide"; got no error
uint32 1/0: expected "divide"; got no error
uint64 1/0: expected "divide"; got no error
uintptr 1/0: expected "divide"; got no error
=========== ken/intervar.go =========== ken/intervar.go
print 1 bio 2 file 3 -- abc print 1 bio 2 file 3 -- abc
......
...@@ -147,10 +147,22 @@ func main() { ...@@ -147,10 +147,22 @@ func main() {
case t.err == "" && err == "": case t.err == "" && err == "":
// fine // fine
case t.err != "" && err == "": case t.err != "" && err == "":
if !bad {
bad = true
fmt.Printf("BUG\n")
}
fmt.Printf("%s: expected %q; got no error\n", t.name, t.err) fmt.Printf("%s: expected %q; got no error\n", t.name, t.err)
case t.err == "" && err != "": case t.err == "" && err != "":
if !bad {
bad = true
fmt.Printf("BUG\n")
}
fmt.Printf("%s: expected no error; got %q\n", t.name, err) fmt.Printf("%s: expected no error; got %q\n", t.name, err)
case t.err != "" && err != "": case t.err != "" && err != "":
if !bad {
bad = true
fmt.Printf("BUG\n")
}
if strings.Index(err, t.err) < 0 { if strings.Index(err, t.err) < 0 {
fmt.Printf("%s: expected %q; got %q\n", t.name, t.err, err) fmt.Printf("%s: expected %q; got %q\n", t.name, t.err, err)
continue continue
......
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