summaryrefslogtreecommitdiff
path: root/src/cmd/6g/gsubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6g/gsubr.c')
-rw-r--r--src/cmd/6g/gsubr.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index 231caa633..25a16a20e 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -1756,11 +1756,11 @@ sudoclean(void)
* to release the register used for a.
*/
int
-sudoaddable(Node *n, Addr *a)
+sudoaddable(int as, Node *n, Addr *a)
{
int o, i, w;
int oary[10];
- vlong v;
+ int64 v;
Node n1, n2, n3, *nn, *l, *r;
Node *reg, *reg1;
Prog *p1;
@@ -1770,8 +1770,13 @@ sudoaddable(Node *n, Addr *a)
return 0;
switch(n->op) {
- default:
- return 0;
+ case OLITERAL:
+ if(n->val.ctype != CTINT)
+ break;
+ v = mpgetfix(n->val.u.xval);
+ if(v >= 32000 || v <= -32000)
+ break;
+ goto lit;
case ODOT:
case ODOTPTR:
@@ -1790,6 +1795,30 @@ sudoaddable(Node *n, Addr *a)
reg1->op = OEMPTY;
goto oindex;
}
+ return 0;
+
+lit:
+ switch(as) {
+ default:
+ return 0;
+ case AADDB: case AADDW: case AADDL: case AADDQ:
+ case ASUBB: case ASUBW: case ASUBL: case ASUBQ:
+ case AANDB: case AANDW: case AANDL: case AANDQ:
+ case AORB: case AORW: case AORL: case AORQ:
+ case AXORB: case AXORW: case AXORL: case AXORQ:
+ case AINCB: case AINCW: case AINCL: case AINCQ:
+ case ADECB: case ADECW: case ADECL: case ADECQ:
+ case AMOVB: case AMOVW: case AMOVL: case AMOVQ:
+ break;
+ }
+
+ cleani += 2;
+ reg = &clean[cleani-1];
+ reg1 = &clean[cleani-2];
+ reg->op = OEMPTY;
+ reg1->op = OEMPTY;
+ naddr(n, a);
+ goto yes;
odot:
o = dotoffset(n, oary, &nn);