Commit c00f9f49 authored by Russ Cox's avatar Russ Cox

6g: avoid too-large immediate constants

R=ken2
CC=golang-dev
https://golang.org/cl/2566042
parent 97f3a80d
...@@ -537,9 +537,7 @@ agen(Node *n, Node *res) ...@@ -537,9 +537,7 @@ agen(Node *n, Node *res)
gmove(&n1, &n3); gmove(&n1, &n3);
} }
nodconst(&n2, types[tptr], v*w); ginscon(optoas(OADD, types[tptr]), v*w, &n3);
gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res); gmove(&n3, res);
regfree(&n3); regfree(&n3);
break; break;
...@@ -596,8 +594,7 @@ agen(Node *n, Node *res) ...@@ -596,8 +594,7 @@ agen(Node *n, Node *res)
p1->from.index = p1->from.type; p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR; p1->from.type = p1->to.type + D_INDIR;
} else { } else {
nodconst(&n1, t, w); ginscon(optoas(OMUL, t), w, &n2);
gins(optoas(OMUL, t), &n1, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3); gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res); gmove(&n3, res);
} }
...@@ -621,10 +618,8 @@ agen(Node *n, Node *res) ...@@ -621,10 +618,8 @@ agen(Node *n, Node *res)
fatal("agen: bad ONAME class %#x", n->class); fatal("agen: bad ONAME class %#x", n->class);
} }
cgen(n->heapaddr, res); cgen(n->heapaddr, res);
if(n->xoffset != 0) { if(n->xoffset != 0)
nodconst(&n1, types[TINT64], n->xoffset); ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
gins(optoas(OADD, types[tptr]), &n1, res);
}
break; break;
case OIND: case OIND:
...@@ -633,10 +628,8 @@ agen(Node *n, Node *res) ...@@ -633,10 +628,8 @@ agen(Node *n, Node *res)
case ODOT: case ODOT:
agen(nl, res); agen(nl, res);
if(n->xoffset != 0) { if(n->xoffset != 0)
nodconst(&n1, types[TINT64], n->xoffset); ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
gins(optoas(OADD, types[tptr]), &n1, res);
}
break; break;
case ODOTPTR: case ODOTPTR:
...@@ -653,8 +646,7 @@ agen(Node *n, Node *res) ...@@ -653,8 +646,7 @@ agen(Node *n, Node *res)
gins(ATESTB, nodintconst(0), &n1); gins(ATESTB, nodintconst(0), &n1);
regfree(&n1); regfree(&n1);
} }
nodconst(&n1, types[TINT64], n->xoffset); ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
gins(optoas(OADD, types[tptr]), &n1, res);
} }
break; break;
} }
......
...@@ -123,6 +123,7 @@ Node* nodarg(Type*, int); ...@@ -123,6 +123,7 @@ Node* nodarg(Type*, int);
void nodreg(Node*, Type*, int); void nodreg(Node*, Type*, int);
void nodindreg(Node*, Type*, int); void nodindreg(Node*, Type*, int);
void gconreg(int, vlong, int); void gconreg(int, vlong, int);
void ginscon(int, vlong, Node*);
void buildtxt(void); void buildtxt(void);
Plist* newplist(void); Plist* newplist(void);
int isfat(Type*); int isfat(Type*);
......
...@@ -1292,10 +1292,8 @@ slicearray: ...@@ -1292,10 +1292,8 @@ slicearray:
if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) { if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
v = mpgetfix(nodes[2].val.u.xval) * v = mpgetfix(nodes[2].val.u.xval) *
mpgetfix(nodes[4].val.u.xval); mpgetfix(nodes[4].val.u.xval);
if(v != 0) { if(v != 0)
nodconst(&n1, types[tptr], v); ginscon(optoas(OADD, types[tptr]), v, &nodes[0]);
gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
}
} else { } else {
regalloc(&n1, types[tptr], &nodes[2]); regalloc(&n1, types[tptr], &nodes[2]);
gmove(&nodes[2], &n1); gmove(&nodes[2], &n1);
...@@ -1409,10 +1407,8 @@ sliceslice: ...@@ -1409,10 +1407,8 @@ sliceslice:
gins(optoas(OAS, types[tptr]), &n2, &n1); gins(optoas(OAS, types[tptr]), &n2, &n1);
v = mpgetfix(nodes[1].val.u.xval) * v = mpgetfix(nodes[1].val.u.xval) *
mpgetfix(nodes[3].val.u.xval); mpgetfix(nodes[3].val.u.xval);
if(v != 0) { if(v != 0)
nodconst(&n2, types[tptr], v); ginscon(optoas(OADD, types[tptr]), v, &n1);
gins(optoas(OADD, types[tptr]), &n2, &n1);
}
} else { } else {
gmove(&nodes[1], &n1); gmove(&nodes[1], &n1);
if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1) if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1)
......
...@@ -430,11 +430,33 @@ fatal("shouldnt be used"); ...@@ -430,11 +430,33 @@ fatal("shouldnt be used");
void void
gconreg(int as, vlong c, int reg) gconreg(int as, vlong c, int reg)
{ {
Node n1, n2; Node nr;
nodreg(&nr, types[TINT64], reg);
ginscon(as, c, &nr);
}
/*
* generate
* as $c, n
*/
void
ginscon(int as, vlong c, Node *n2)
{
Node n1, ntmp;
nodconst(&n1, types[TINT64], c); nodconst(&n1, types[TINT64], c);
nodreg(&n2, types[TINT64], reg);
gins(as, &n1, &n2); if(as != AMOVQ && (c < -1LL<<31 || c >= 1LL<<31)) {
// cannot have 64-bit immediokate in ADD, etc.
// instead, MOV into register first.
regalloc(&ntmp, types[TINT64], N);
gins(AMOVQ, &n1, &ntmp);
gins(as, &ntmp, n2);
regfree(&ntmp);
return;
}
gins(as, &n1, n2);
} }
#define CASE(a,b) (((a)<<16)|((b)<<0)) #define CASE(a,b) (((a)<<16)|((b)<<0))
......
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