summaryrefslogtreecommitdiff
path: root/src/cmd/8g/cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8g/cgen.c')
-rw-r--r--src/cmd/8g/cgen.c69
1 files changed, 41 insertions, 28 deletions
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index 8fbdc6ee7..875d434fa 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -175,7 +175,7 @@ cgen(Node *n, Node *res)
case OREAL:
case OIMAG:
case OCMPLX:
- // TODO compile complex
+ fatal("unexpected complex");
return;
// these call bgen to get a bool value
@@ -230,8 +230,8 @@ cgen(Node *n, Node *res)
cgen(nl, res);
break;
}
- mgen(nl, &n1, res);
tempname(&n2, n->type);
+ mgen(nl, &n1, res);
gmove(&n1, &n2);
gmove(&n2, res);
mfree(&n1);
@@ -392,23 +392,16 @@ uop: // unary
gmove(&n1, res);
return;
-flt: // floating-point. 387 (not SSE2) to interoperate with 6c
+flt: // floating-point. 387 (not SSE2) to interoperate with 8c
nodreg(&f0, nl->type, D_F0);
nodreg(&f1, n->type, D_F0+1);
if(nr != N)
goto flt2;
- if(n->op == OMINUS) {
- nr = nodintconst(-1);
- convlit(&nr, n->type);
- n->op = OMUL;
- goto flt2;
- }
-
// unary
cgen(nl, &f0);
if(n->op != OCONV && n->op != OPLUS)
- gins(foptoas(n->op, n->type, 0), &f0, &f0);
+ gins(foptoas(n->op, n->type, 0), N, N);
gmove(&f0, res);
return;
@@ -525,9 +518,11 @@ agen(Node *n, Node *res)
p2 = nil; // to be patched to panicindex.
w = n->type->width;
if(nr->addable) {
- agenr(nl, &n3, res);
- if(!isconst(nr, CTINT)) {
+ if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]);
+ if(!isconst(nl, CTSTR))
+ agenr(nl, &n3, res);
+ if(!isconst(nr, CTINT)) {
p2 = cgenindex(nr, &tmp);
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
@@ -539,13 +534,16 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
- regalloc(&n3, types[tptr], res);
- agen(nl, &n3);
+ if(!isconst(nl, CTSTR)) {
+ regalloc(&n3, types[tptr], res);
+ agen(nl, &n3);
+ }
} else {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
nr = &tmp;
- agenr(nl, &n3, res);
+ if(!isconst(nl, CTSTR))
+ agenr(nl, &n3, res);
regalloc(&n1, tmp.type, N);
gins(optoas(OAS, tmp.type), &tmp, &n1);
}
@@ -556,7 +554,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough
// that we might derive too big a pointer.
- if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
+ if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4);
n4.op = OINDREG;
@@ -571,9 +569,10 @@ agen(Node *n, Node *res)
// constant index
if(isconst(nr, CTINT)) {
+ if(isconst(nl, CTSTR))
+ fatal("constant string constant index");
v = mpgetfix(nr->val.u.xval);
- if(isslice(nl->type)) {
-
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) {
n1 = n3;
n1.op = OINDREG;
@@ -591,13 +590,6 @@ agen(Node *n, Node *res)
n1.type = types[tptr];
n1.xoffset = Array_array;
gmove(&n1, &n3);
- } else
- if(!debug['B'] && !n->etype) {
- if(v < 0)
- yyerror("out of bounds on array");
- else
- if(v >= nl->type->bound)
- yyerror("out of bounds on array");
}
nodconst(&n2, types[tptr], v*w);
@@ -614,7 +606,9 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) {
// check bounds
- if(isslice(nl->type)) {
+ if(isconst(nl, CTSTR))
+ nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
+ else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@@ -628,8 +622,17 @@ agen(Node *n, Node *res)
ginscall(panicindex, 0);
patch(p1, pc);
}
+
+ if(isconst(nl, CTSTR)) {
+ regalloc(&n3, types[tptr], res);
+ p1 = gins(ALEAL, N, &n3);
+ datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+ p1->from.scale = 1;
+ p1->from.index = n2.val.u.reg;
+ goto indexdone;
+ }
- if(isslice(nl->type)) {
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@@ -649,6 +652,7 @@ agen(Node *n, Node *res)
gmove(&n3, res);
}
+ indexdone:
gmove(&n3, res);
regfree(&n2);
regfree(&n3);
@@ -724,8 +728,14 @@ igen(Node *n, Node *a, Node *res)
{
Node n1;
+ // release register for now, to avoid
+ // confusing tempname.
+ if(res != N && res->op == OREGISTER)
+ reg[res->val.u.reg]--;
tempname(&n1, types[tptr]);
agen(n, &n1);
+ if(res != N && res->op == OREGISTER)
+ reg[res->val.u.reg]++;
regalloc(a, types[tptr], res);
gmove(&n1, a);
a->op = OINDREG;
@@ -768,6 +778,9 @@ bgen(Node *n, int true, Prog *to)
if(n == N)
n = nodbool(1);
+ if(n->ninit != nil)
+ genlist(n->ninit);
+
nl = n->left;
nr = n->right;