summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/6g/gen.c109
-rw-r--r--src/cmd/6g/gg.h1
-rw-r--r--src/cmd/6g/gsubr.c95
-rw-r--r--src/cmd/gc/const.c18
-rw-r--r--src/cmd/gc/go.h1
5 files changed, 126 insertions, 98 deletions
diff --git a/src/cmd/6g/gen.c b/src/cmd/6g/gen.c
index 400aa7eac..3b6a5e4d4 100644
--- a/src/cmd/6g/gen.c
+++ b/src/cmd/6g/gen.c
@@ -915,55 +915,96 @@ cgen_asop(Node *n)
{
Node n1, n2, n3, n4;
Node *nl, *nr;
+ Prog *p1;
+ Addr addr;
nl = n->left;
nr = n->right;
- if(nl->addable && nr->op == OLITERAL)
+ 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(!isint[nl->type->etype])
- break;
- if(mpgetfix(nr->val.u.xval) != 1)
- break;
- gins(optoas(OINC, nl->type), N, nl);
- goto ret;
+ if(smallintconst(nr))
+ if(mpgetfix(nr->val.u.xval) == 1) {
+ if(nl->addable) {
+ gins(optoas(OINC, nl->type), N, nl);
+ goto ret;
+ }
+ if(sudoaddable(nl, nr->type, &addr)) {
+ p1 = gins(optoas(OINC, nl->type), N, N);
+ p1->to = addr;
+ sudoclean();
+ goto ret;
+ }
+ }
+ break;
+
case OSUB:
- if(!isint[nl->type->etype])
- break;
- if(mpgetfix(nr->val.u.xval) != 1)
- break;
- gins(optoas(ODEC, nl->type), N, nl);
- goto ret;
+ if(smallintconst(nr))
+ if(mpgetfix(nr->val.u.xval) == 1) {
+ if(nl->addable) {
+ gins(optoas(ODEC, nl->type), N, nl);
+ goto ret;
+ }
+ if(sudoaddable(nl, nr->type, &addr)) {
+ p1 = gins(optoas(ODEC, nl->type), N, N);
+ p1->to = addr;
+ sudoclean();
+ goto ret;
+ }
+ }
+ break;
}
- if(nl->addable)
switch(n->etype) {
+ case OADD:
+ case OSUB:
case OXOR:
case OAND:
case OOR:
- case OADD:
- case OSUB:
- if(!isint[nl->type->etype])
- break;
- if(!isint[nr->type->etype])
- break;
- regalloc(&n2, nr->type, N);
- cgen(nr, &n2);
- gins(optoas(n->etype, nl->type), &n2, nl);
- regfree(&n2);
- goto ret;
- }
-
- 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(nl->addable) {
+ if(smallintconst(nr)) {
+ gins(optoas(n->etype, nl->type), nr, nl);
+ goto ret;
+ }
+ regalloc(&n2, nr->type, N);
+ cgen(nr, &n2);
+ gins(optoas(n->etype, nl->type), &n2, nl);
+ regfree(&n2);
+ goto ret;
+ }
+ if(nr->ullman < UINF)
+ if(sudoaddable(nl, nr->type, &addr)) {
+ if(smallintconst(nr)) {
+ p1 = gins(optoas(n->etype, nl->type), nr, N);
+ p1->to = addr;
+ sudoclean();
+ goto ret;
+ }
+ regalloc(&n2, nr->type, N);
+ cgen(nr, &n2);
+ p1 = gins(optoas(n->etype, nl->type), &n2, N);
+ p1->to = addr;
+ regfree(&n2);
+ sudoclean();
+ goto ret;
+ }
}
+hard:
if(nr->ullman > nl->ullman) {
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 051fa1215..80a548f8a 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -199,7 +199,6 @@ void tempname(Node*, Type*);
Plist* newplist(void);
int isfat(Type*);
void setmaxarg(Type*);
-int smallintconst(Node*);
void sudoclean(void);
int sudoaddable(Node*, Type*, Addr*);
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index c4798b77e..daaf71321 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -102,6 +102,19 @@ newplist(void)
return pl;
}
+static int resvd[] =
+{
+// D_DI, // for movstring
+// D_SI, // for movstring
+
+ D_AX, // for divide
+ D_CX, // for shift
+ D_DX, // for divide
+ D_SP, // for stack
+ D_R14, // reserved for m
+ D_R15, // reserved for u
+};
+
void
ginit(void)
{
@@ -114,15 +127,8 @@ ginit(void)
for(i=D_X0; i<=D_X7; i++)
reg[i] = 0;
-// reg[D_DI]++; // for movstring
-// reg[D_SI]++; // for movstring
-
- reg[D_AX]++; // for divide
- reg[D_CX]++; // for shift
- reg[D_DX]++; // for divide
- reg[D_SP]++; // for stack
- reg[D_R14]++; // reserved for m
- reg[D_R15]++; // reserved for u
+ for(i=0; i<nelem(resvd); i++)
+ reg[resvd[i]]++;
}
void
@@ -130,15 +136,8 @@ gclean(void)
{
int i;
-// reg[D_DI]--; // for movstring
-// reg[D_SI]--; // for movstring
-
- reg[D_AX]--; // for divide
- reg[D_CX]--; // for shift
- reg[D_DX]--; // for divide
- reg[D_SP]--; // for stack
- reg[D_R14]--; // reserved for m
- reg[D_R15]--; // reserved for u
+ for(i=0; i<nelem(resvd); i++)
+ reg[resvd[i]]--;
for(i=D_AX; i<=D_R15; i++)
if(reg[i])
@@ -1817,24 +1816,6 @@ dotoffset(Node *n, int *oary, Node **nn)
return i;
}
-int
-smallintconst(Node *n)
-{
- if(n->op == OLITERAL)
- switch(simtype[n->type->etype]) {
- case TINT8:
- case TUINT8:
- case TINT16:
- case TUINT16:
- case TINT32:
- case TUINT32:
- case TBOOL:
- case TPTR32:
- return 1;
- }
- return 0;
-}
-
enum
{
ODynam = 1<<0,
@@ -1857,37 +1838,36 @@ sudoclean(void)
int
sudoaddable(Node *n, Type *t, Addr *a)
{
- int et, o, i, w;
+ int o, i, w;
int oary[10];
vlong v;
- Node n0, n1, n2, *nn, *l, *r;
+ Node n1, n2, *nn, *l, *r;
Node *reg, *reg1;
Prog *p1;
- // make a cleanup slot
- cleani += 2;
- reg = &clean[cleani-1];
- reg1 = &clean[cleani-2];
- reg->op = OEMPTY;
- reg1->op = OEMPTY;
-
if(n->type == T || t == T)
- goto no;
- et = simtype[n->type->etype];
- if(et != simtype[t->etype])
- goto no;
+ return 0;
switch(n->op) {
default:
- goto no;
+ return 0;
case ODOT:
case ODOTPTR:
+ cleani += 2;
+ reg = &clean[cleani-1];
+ reg1 = &clean[cleani-2];
+ reg->op = OEMPTY;
+ reg1->op = OEMPTY;
goto odot;
case OINDEXPTR:
- goto no;
case OINDEX:
+ cleani += 2;
+ reg = &clean[cleani-1];
+ reg1 = &clean[cleani-2];
+ reg->op = OEMPTY;
+ reg1->op = OEMPTY;
goto oindex;
}
@@ -1895,15 +1875,6 @@ odot:
o = dotoffset(n, oary, &nn);
if(nn == N)
goto no;
-
- if(0) {
- dump("\nXX", n);
- dump("YY", nn);
- for(i=0; i<o; i++)
- print(" %d", oary[i]);
- print("\n");
- goto no;
- }
regalloc(reg, types[tptr], N);
n1 = *reg;
@@ -1931,7 +1902,7 @@ odot:
oindex:
l = n->left;
r = n->right;
- if(l->ullman >= UINF || r->ullman >= UINF)
+ if(l->ullman >= UINF && r->ullman >= UINF)
goto no;
// set o to type of array
@@ -1950,8 +1921,6 @@ oindex:
}
w = n->type->width;
- if(w == 0)
- fatal("index is zero width");
if(whatis(r) == Wlitint)
goto oindex_const;
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index d8e38300d..b903d582d 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -540,3 +540,21 @@ cmpslit(Node *l, Node *r)
return +1;
return -1;
}
+
+int
+smallintconst(Node *n)
+{
+ if(n->op == OLITERAL)
+ switch(simtype[n->type->etype]) {
+ case TINT8:
+ case TUINT8:
+ case TINT16:
+ case TUINT16:
+ case TINT32:
+ case TUINT32:
+ case TBOOL:
+ case TPTR32:
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 81371f41d..858afc1c1 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -826,6 +826,7 @@ void convlit1(Node*, Type*, int);
void convlit(Node*, Type*);
void evconst(Node*);
int cmpslit(Node *l, Node *r);
+int smallintconst(Node*);
/*
* gen.c/gsubr.c/obj.c