summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/7c/cgen.c12
-rw-r--r--sys/src/cmd/7c/peep.c21
-rw-r--r--sys/src/cmd/7c/reg.c1
-rw-r--r--sys/src/cmd/7c/txt.c30
4 files changed, 49 insertions, 15 deletions
diff --git a/sys/src/cmd/7c/cgen.c b/sys/src/cmd/7c/cgen.c
index ecdab98ba..bfef2fd4e 100644
--- a/sys/src/cmd/7c/cgen.c
+++ b/sys/src/cmd/7c/cgen.c
@@ -390,7 +390,7 @@ cgenrel(Node *n, Node *nn, int inrel)
r = l;
while(r->op == OADD)
r = r->right;
- if(sconst(r) && (v = r->vconst+nod.xoffset) >= -4096 && v < 4096) {
+ if(usableoffset(n, nod.xoffset, r)){
v = r->vconst;
r->vconst = 0;
cgen(l, &nod);
@@ -613,7 +613,7 @@ reglcgen(Node *t, Node *n, Node *nn)
r = n->left;
while(r->op == OADD)
r = r->right;
- if(sconst(r) && (v = r->vconst+t->xoffset) >= -4096 && v < 4096) {
+ if(usableoffset(n, t->xoffset, r)) {
v = r->vconst;
r->vconst = 0;
lcgen(n, t);
@@ -623,11 +623,17 @@ reglcgen(Node *t, Node *n, Node *nn)
return;
}
} else if(n->op == OINDREG) {
- if((v = n->xoffset) >= -4096 && v < 4096) {
+ if(usableoffset(n, t->xoffset+n->xoffset, nil)) {
+ Type *tt = n->type;
+ n->type = types[TIND];
n->op = OREGISTER;
+ v = n->xoffset;
+ n->xoffset = 0;
cgen(n, t);
t->xoffset += v;
+ n->xoffset = v;
n->op = OINDREG;
+ n->type = tt;
regind(t, n);
return;
}
diff --git a/sys/src/cmd/7c/peep.c b/sys/src/cmd/7c/peep.c
index 557af7b18..8d07cfcc9 100644
--- a/sys/src/cmd/7c/peep.c
+++ b/sys/src/cmd/7c/peep.c
@@ -2,6 +2,9 @@
int xtramodes(Reg*, Adr*);
+Reg* findpre(Reg *r, Adr *v);
+Reg* findinc(Reg *r, Reg *r2, Adr *v);
+
void
peep(void)
{
@@ -55,6 +58,21 @@ loop1:
t++;
}
}
+ if(p->as == ASXTW){
+ r1 = findpre(r, &p->from);
+ if(r1 != R){
+ p1 = r1->prog;
+ switch(p1->as){
+ case AMOVB:
+ case AMOVBU:
+ case AMOVH:
+ case AMOVHU:
+ case AMOVW:
+ p->as = AMOVW;
+ break;
+ }
+ }
+ }
if(p->as == AMOV || p->as == AMOVW || p->as == AFMOVS || p->as == AFMOVD)
if(regtyp(&p->to)) {
if(p->from.type == D_CONST)
@@ -425,6 +443,7 @@ subprop(Reg *r0)
case AFMOVD:
case AMOVW:
case AMOV:
+ case ASXTW:
if(p->to.type == v1->type)
if(p->to.reg == v1->reg)
goto gotit;
@@ -954,8 +973,8 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVBU:
case AMOVW:
case AMOVWU:
+ case ASXTW:
case AMOV:
-
case AMVN:
case AMVNW:
case ANEG:
diff --git a/sys/src/cmd/7c/reg.c b/sys/src/cmd/7c/reg.c
index 174ffd7e0..d992ba8f9 100644
--- a/sys/src/cmd/7c/reg.c
+++ b/sys/src/cmd/7c/reg.c
@@ -150,6 +150,7 @@ regopt(Prog *p)
case AMOVHU:
case AMOVW:
case AMOVWU:
+ case ASXTW:
case AFMOVS:
case AFCVTSD:
case AFMOVD:
diff --git a/sys/src/cmd/7c/txt.c b/sys/src/cmd/7c/txt.c
index 4a345cf46..96a9eaf86 100644
--- a/sys/src/cmd/7c/txt.c
+++ b/sys/src/cmd/7c/txt.c
@@ -761,7 +761,10 @@ gmove(Node *f, Node *t)
case TVLONG:
case TUVLONG:
case TIND:
- a = AMOV;
+ if(typeu[ft])
+ a = AMOVWU;
+ else
+ a = ASXTW;
break;
}
break;
@@ -785,14 +788,16 @@ gmove(Node *f, Node *t)
case TUINT:
case TLONG:
case TULONG:
- case TVLONG:
- case TUVLONG:
- case TIND:
case TSHORT:
case TUSHORT:
case TCHAR:
case TUCHAR:
- a = AMOV; /* TO DO: conversion done? */
+ a = AMOVWU;
+ break;
+ case TVLONG:
+ case TUVLONG:
+ case TIND:
+ a = AMOV;
break;
}
break;
@@ -1323,16 +1328,19 @@ sval(vlong v)
int
usableoffset(Node *n, vlong o, Node *v)
{
- int s, et;
+ int s;
- et = v->type->etype;
- if(v->op != OCONST || typefd[et])
- return 0;
+ if(v != nil){
+ if(v->op != OCONST || typefd[v->type->etype])
+ return 0;
+ o += v->vconst;
+ }
s = n->type->width;
if(s > 16)
s = 16;
- o += v->vconst;
- return o >= -256 || o < 4095*s;
+ if((o % s) != 0)
+ return 0;
+ return o >= -256 && o < 4096*s;
}
long