diff options
| -rw-r--r-- | sys/src/cmd/7c/cgen.c | 12 | ||||
| -rw-r--r-- | sys/src/cmd/7c/peep.c | 21 | ||||
| -rw-r--r-- | sys/src/cmd/7c/reg.c | 1 | ||||
| -rw-r--r-- | sys/src/cmd/7c/txt.c | 30 |
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 |
