summaryrefslogtreecommitdiff
path: root/src/cmd/5g/cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5g/cgen.c')
-rw-r--r--src/cmd/5g/cgen.c104
1 files changed, 69 insertions, 35 deletions
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
index 1328f4be6..032409bae 100644
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -169,7 +169,7 @@ cgen(Node *n, Node *res)
case OREAL:
case OIMAG:
- case OCMPLX:
+ case OCOMPLEX:
fatal("unexpected complex");
break;
@@ -567,7 +567,8 @@ agen(Node *n, Node *res)
regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1);
}
- } else if(nl->addable) {
+ } else
+ if(nl->addable) {
if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp);
@@ -671,7 +672,8 @@ agen(Node *n, Node *res)
p1 = gins(AMOVW, N, &n3);
datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
p1->from.type = D_CONST;
- } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
+ } else
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@@ -813,6 +815,28 @@ agenr(Node *n, Node *a, Node *res)
agen(n, a);
}
+void
+gencmp0(Node *n, Type *t, int o, Prog *to)
+{
+ Node n1, n2, n3;
+ int a;
+
+ regalloc(&n1, t, N);
+ cgen(n, &n1);
+ a = optoas(OCMP, t);
+ if(a != ACMP) {
+ nodconst(&n2, t, 0);
+ regalloc(&n3, t, N);
+ gmove(&n2, &n3);
+ gcmp(a, &n1, &n3);
+ regfree(&n3);
+ } else
+ gins(ATST, &n1, N);
+ a = optoas(o, t);
+ patch(gbranch(a, t), to);
+ regfree(&n1);
+}
+
/*
* generate:
* if(n == true) goto to;
@@ -855,19 +879,10 @@ bgen(Node *n, int true, Prog *to)
switch(n->op) {
default:
- def:
- regalloc(&n1, n->type, N);
- cgen(n, &n1);
- nodconst(&n2, n->type, 0);
- regalloc(&n3, n->type, N);
- gmove(&n2, &n3);
- gcmp(optoas(OCMP, n->type), &n1, &n3);
- a = ABNE;
+ a = ONE;
if(!true)
- a = ABEQ;
- patch(gbranch(a, n->type), to);
- regfree(&n1);
- regfree(&n3);
+ a = OEQ;
+ gencmp0(n, n->type, a, to);
goto ret;
case OLITERAL:
@@ -876,23 +891,6 @@ bgen(Node *n, int true, Prog *to)
patch(gbranch(AB, T), to);
goto ret;
- case ONAME:
- if(n->addable == 0)
- goto def;
- nodconst(&n1, n->type, 0);
- regalloc(&n2, n->type, N);
- regalloc(&n3, n->type, N);
- gmove(&n1, &n2);
- cgen(n, &n3);
- gcmp(optoas(OCMP, n->type), &n2, &n3);
- a = ABNE;
- if(!true)
- a = ABEQ;
- patch(gbranch(a, n->type), to);
- regfree(&n2);
- regfree(&n3);
- goto ret;
-
case OANDAND:
if(!true)
goto caseor;
@@ -975,6 +973,16 @@ bgen(Node *n, int true, Prog *to)
yyerror("illegal array comparison");
break;
}
+
+ regalloc(&n1, types[tptr], N);
+ agen(nl, &n1);
+ n2 = n1;
+ n2.op = OINDREG;
+ n2.xoffset = Array_array;
+ gencmp0(&n2, types[tptr], a, to);
+ regfree(&n1);
+ break;
+
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
regalloc(&n3, types[tptr], N);
@@ -1000,6 +1008,16 @@ bgen(Node *n, int true, Prog *to)
yyerror("illegal interface comparison");
break;
}
+
+ regalloc(&n1, types[tptr], N);
+ agen(nl, &n1);
+ n2 = n1;
+ n2.op = OINDREG;
+ n2.xoffset = 0;
+ gencmp0(&n2, types[tptr], a, to);
+ regfree(&n1);
+ break;
+
a = optoas(a, types[tptr]);
regalloc(&n1, types[tptr], N);
regalloc(&n3, types[tptr], N);
@@ -1039,6 +1057,17 @@ bgen(Node *n, int true, Prog *to)
break;
}
+ if(nr->op == OLITERAL) {
+ if(nr->val.ctype == CTINT && mpgetfix(nr->val.u.xval) == 0) {
+ gencmp0(nl, nl->type, a, to);
+ break;
+ }
+ if(nr->val.ctype == CTNIL) {
+ gencmp0(nl, nl->type, a, to);
+ break;
+ }
+ }
+
a = optoas(a, nr->type);
if(nr->ullman >= UINF) {
@@ -1063,11 +1092,17 @@ bgen(Node *n, int true, Prog *to)
break;
}
+ tempname(&n3, nl->type);
+ cgen(nl, &n3);
+
+ tempname(&tmp, nr->type);
+ cgen(nr, &tmp);
+
regalloc(&n1, nl->type, N);
- cgen(nl, &n1);
+ gmove(&n3, &n1);
regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
+ gmove(&tmp, &n2);
gcmp(optoas(OCMP, nr->type), &n1, &n2);
if(isfloat[nl->type->etype]) {
@@ -1080,7 +1115,6 @@ bgen(Node *n, int true, Prog *to)
} else {
patch(gbranch(a, nr->type), to);
}
-
regfree(&n1);
regfree(&n2);
break;