Commit f50e7b15 authored by Kai Backman's avatar Kai Backman

mostly 64 bit support.

- fixed a number of places where we tried to allocate 64bit
  regs. added honeypot in regalloc to catch these in the future.
- implemented quad copying in sgen
- cgen64.c, add, mul
- clearfat done
- D_REGREG output from 5g (linker already knew about them)
- gmove done
- optoas almost done, last bit probably not needed
- D_SHIFT support in list.c

R=rsc
APPROVED=rsc
DELTA=963  (711 added, 112 deleted, 140 changed)
OCL=33619
CL=33688
parent 1f1551f1
...@@ -14,13 +14,14 @@ HFILES=\ ...@@ -14,13 +14,14 @@ HFILES=\
opt.h\ opt.h\
OFILES=\ OFILES=\
../5l/enam.$O\
list.$O\ list.$O\
gobj.$O\
galign.$O\ galign.$O\
gobj.$O\
ggen.$O\ ggen.$O\
cgen.$O\
gsubr.$O\ gsubr.$O\
../5l/enam.$O\ cgen.$O\
cgen64.$O
LIB=\ LIB=\
../gc/gc.a$O ../gc/gc.a$O
......
...@@ -4,6 +4,35 @@ ...@@ -4,6 +4,35 @@
#include "gg.h" #include "gg.h"
void
mgen(Node *n, Node *n1, Node *rg)
{
n1->ostk = 0;
n1->op = OEMPTY;
if(n->addable) {
*n1 = *n;
n1->ostk = 0;
if(n1->op == OREGISTER || n1->op == OINDREG)
reg[n->val.u.reg]++;
return;
}
if(n->type->width > widthptr)
tempalloc(n1, n->type);
else
regalloc(n1, n->type, rg);
cgen(n, n1);
}
void
mfree(Node *n)
{
if(n->ostk)
tempfree(n);
else if(n->op == OREGISTER)
regfree(n);
}
/* /*
* generate: * generate:
* res = n; * res = n;
...@@ -124,22 +153,42 @@ cgen(Node *n, Node *res) ...@@ -124,22 +153,42 @@ cgen(Node *n, Node *res)
goto ret; goto ret;
} }
a = optoas(OAS, n->type); // 64-bit ops are hard on 32-bit machine.
if(sudoaddable(a, n, &addr, &w)) { if(is64(n->type) || is64(res->type) || n->left != N && is64(n->left->type)) {
if(res->op == OREGISTER) { print("64 bit op %O\n", n->op);
p1 = gins(a, N, res); switch(n->op) {
p1->from = addr; // math goes to cgen64.
p1->reg = w; case OMINUS:
} else { case OCOM:
regalloc(&n2, n->type, N); case OADD:
p1 = gins(a, N, &n2); case OSUB:
p1->from = addr; case OMUL:
p1->reg = w; case OLSH:
gins(a, &n2, res); case ORSH:
regfree(&n2); case OAND:
case OOR:
case OXOR:
cgen64(n, res);
return;
}
} else {
a = optoas(OAS, n->type);
if(sudoaddable(a, n, &addr, &w)) {
if(res->op == OREGISTER) {
p1 = gins(a, N, res);
p1->from = addr;
p1->reg = w;
} else {
regalloc(&n2, n->type, N);
p1 = gins(a, N, &n2);
p1->from = addr;
p1->reg = w;
gins(a, &n2, res);
regfree(&n2);
}
sudoclean();
goto ret;
} }
sudoclean();
goto ret;
} }
switch(n->op) { switch(n->op) {
...@@ -207,10 +256,13 @@ cgen(Node *n, Node *res) ...@@ -207,10 +256,13 @@ cgen(Node *n, Node *res)
goto abop; goto abop;
case OCONV: case OCONV:
regalloc(&n1, nl->type, res); if(eqtype(n->type, nl->type) || noconv(n->type, nl->type)) {
cgen(nl, &n1); cgen(nl, res);
break;
}
mgen(nl, &n1, res);
gmove(&n1, res); gmove(&n1, res);
regfree(&n1); mfree(&n1);
break; break;
case ODOT: case ODOT:
...@@ -358,11 +410,8 @@ agen(Node *n, Node *res) ...@@ -358,11 +410,8 @@ agen(Node *n, Node *res)
dump("\nagen-res", res); dump("\nagen-res", res);
dump("agen-r", n); dump("agen-r", n);
} }
if(n == N || n->type == T) if(n == N || n->type == T || res == N || res->type == T)
return; fatal("agen");
if(!isptr[res->type->etype])
fatal("agen: not tptr: %T", res->type);
while(n->op == OCONVNOP) while(n->op == OCONVNOP)
n = n->left; n = n->left;
...@@ -828,7 +877,7 @@ sgen(Node *n, Node *res, int32 w) ...@@ -828,7 +877,7 @@ sgen(Node *n, Node *res, int32 w)
{ {
Node dst, src, tmp, nend; Node dst, src, tmp, nend;
int32 c, q, odst, osrc; int32 c, q, odst, osrc;
Prog *p; Prog *p, *ploop;
if(debug['g']) { if(debug['g']) {
print("\nsgen w=%d\n", w); print("\nsgen w=%d\n", w);
...@@ -848,6 +897,9 @@ sgen(Node *n, Node *res, int32 w) ...@@ -848,6 +897,9 @@ sgen(Node *n, Node *res, int32 w)
osrc = stkof(n); osrc = stkof(n);
odst = stkof(res); odst = stkof(res);
if(osrc % 4 != 0 || odst %4 != 0)
fatal("sgen: non word(4) aligned offset src %d or dst %d", osrc, odst);
regalloc(&dst, types[tptr], N); regalloc(&dst, types[tptr], N);
regalloc(&src, types[tptr], N); regalloc(&src, types[tptr], N);
regalloc(&tmp, types[TUINT32], N); regalloc(&tmp, types[TUINT32], N);
...@@ -866,44 +918,54 @@ sgen(Node *n, Node *res, int32 w) ...@@ -866,44 +918,54 @@ sgen(Node *n, Node *res, int32 w)
// if we are copying forward on the stack and // if we are copying forward on the stack and
// the src and dst overlap, then reverse direction // the src and dst overlap, then reverse direction
if(osrc < odst && odst < osrc+w) { if(osrc < odst && odst < osrc+w) {
fatal("sgen reverse copy not implemented"); if(c != 0)
// // reverse direction fatal("sgen: reverse character copy not implemented");
// gins(ASTD, N, N); // set direction flag if(q >= 4) {
// if(c > 0) { regalloc(&nend, types[TUINT32], N);
// gconreg(AADDQ, w-1, D_SI); // set up end marker to 4 bytes before source
// gconreg(AADDQ, w-1, D_DI); p = gins(AMOVW, &src, &nend);
p->from.type = D_CONST;
// gconreg(AMOVQ, c, D_CX); p->from.offset = -4;
// gins(AREP, N, N); // repeat
// gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)- // move src and dest to the end of block
// } p = gins(AMOVW, &src, &src);
p->from.type = D_CONST;
// if(q > 0) { p->from.offset = (q-1)*4;
// if(c > 0) {
// gconreg(AADDQ, -7, D_SI); p = gins(AMOVW, &dst, &dst);
// gconreg(AADDQ, -7, D_DI); p->from.type = D_CONST;
// } else { p->from.offset = (q-1)*4;
// gconreg(AADDQ, w-8, D_SI);
// gconreg(AADDQ, w-8, D_DI); p = gins(AMOVW, &src, &tmp);
// } p->from.type = D_OREG;
// gconreg(AMOVQ, q, D_CX); p->from.offset = -4;
// gins(AREP, N, N); // repeat p->scond |= C_PBIT;
// gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)- ploop = p;
// }
// // we leave with the flag clear p = gins(AMOVW, &tmp, &dst);
// gins(ACLD, N, N); p->to.type = D_OREG;
p->to.offset = -4;
p->scond |= C_PBIT;
gins(ACMP, &src, &nend);
patch(gbranch(ABNE, T), ploop);
regfree(&nend);
}
} else { } else {
// normal direction // normal direction
if(q >= 4) { if(q >= 4) {
regalloc(&nend, types[TUINT32], N); regalloc(&nend, types[TUINT32], N);
p = gins(AMOVW, &src, &nend); p = gins(AMOVW, &src, &nend);
p->from.type = D_CONST; p->from.type = D_CONST;
p->from.offset = q; p->from.offset = q*4;
p = gins(AMOVW, &src, &tmp); p = gins(AMOVW, &src, &tmp);
p->from.type = D_OREG; p->from.type = D_OREG;
p->from.offset = 4; p->from.offset = 4;
p->scond |= C_PBIT; p->scond |= C_PBIT;
ploop = p;
p = gins(AMOVW, &tmp, &dst); p = gins(AMOVW, &tmp, &dst);
p->to.type = D_OREG; p->to.type = D_OREG;
...@@ -911,9 +973,9 @@ sgen(Node *n, Node *res, int32 w) ...@@ -911,9 +973,9 @@ sgen(Node *n, Node *res, int32 w)
p->scond |= C_PBIT; p->scond |= C_PBIT;
gins(ACMP, &src, &nend); gins(ACMP, &src, &nend);
fatal("sgen loop not implemented");
p = gins(ABNE, N, N); patch(gbranch(ABNE, T), ploop);
// TODO(PC offset)
regfree(&nend); regfree(&nend);
} else } else
while(q > 0) { while(q > 0) {
...@@ -931,16 +993,7 @@ sgen(Node *n, Node *res, int32 w) ...@@ -931,16 +993,7 @@ sgen(Node *n, Node *res, int32 w)
} }
if (c != 0) if (c != 0)
fatal("sgen character copy not implemented"); fatal("sgen: character copy not implemented");
// if(c >= 4) {
// gins(AMOVSL, N, N); // MOVL *(SI)+,*(DI)+
// c -= 4;
// }
// while(c > 0) {
// gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
// c--;
// }
} }
regfree(&dst); regfree(&dst);
regfree(&src); regfree(&src);
......
This diff is collapsed.
...@@ -99,6 +99,12 @@ void raddr(Node *n, Prog *p); ...@@ -99,6 +99,12 @@ void raddr(Node *n, Prog *p);
void naddr(Node*, Addr*); void naddr(Node*, Addr*);
void cgen_aret(Node*, Node*); void cgen_aret(Node*, Node*);
/*
* cgen64.c
*/
void cmp64(Node*, Node*, int, Prog*);
void cgen64(Node*, Node*);
/* /*
* gsubr.c * gsubr.c
*/ */
...@@ -124,14 +130,16 @@ void tempfree(Node*); ...@@ -124,14 +130,16 @@ void tempfree(Node*);
Node* nodarg(Type*, int); 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 buildtxt(void); void buildtxt(void);
Plist* newplist(void); Plist* newplist(void);
int isfat(Type*); int isfat(Type*);
int dotaddable(Node*, Node*);
void sudoclean(void); void sudoclean(void);
int sudoaddable(int, Node*, Addr*, int*); int sudoaddable(int, Node*, Addr*, int*);
void afunclit(Addr*); void afunclit(Addr*);
void datagostring(Strlit*, Addr*); void datagostring(Strlit*, Addr*);
void split64(Node*, Node*, Node*);
void splitclean(void);
/* /*
* obj.c * obj.c
......
...@@ -435,8 +435,8 @@ void ...@@ -435,8 +435,8 @@ void
clearfat(Node *nl) clearfat(Node *nl)
{ {
uint32 w, c, q; uint32 w, c, q;
Node dst, nc, nz; Node dst, nc, nz, end;
Prog *p; Prog *p, *pl;
/* clear a fat object */ /* clear a fat object */
if(debug['g']) if(debug['g'])
...@@ -453,10 +453,21 @@ clearfat(Node *nl) ...@@ -453,10 +453,21 @@ clearfat(Node *nl)
cgen(&nc, &nz); cgen(&nc, &nz);
if(q >= 4) { if(q >= 4) {
fatal("clearfat q >=4 not implemented"); regalloc(&end, types[tptr], N);
// gconreg(AMOVQ, q, D_CX); p = gins(AMOVW, &dst, &end);
// gins(AREP, N, N); // repeat p->from.type = D_CONST;
// gins(ASTOSQ, N, N); // STOQ AL,*(DI)+ p->from.offset = q*4;
p = gins(AMOVW, &nz, &dst);
p->to.type = D_OREG;
p->to.offset = 4;
p->scond |= C_PBIT;
pl = p;
gins(ACMP, &dst, &end);
patch(gbranch(ABNE, T), pl);
regfree(&end);
} else } else
while(q > 0) { while(q > 0) {
p = gins(AMOVW, &nz, &dst); p = gins(AMOVW, &nz, &dst);
...@@ -468,7 +479,7 @@ clearfat(Node *nl) ...@@ -468,7 +479,7 @@ clearfat(Node *nl)
} }
while(c > 0) { while(c > 0) {
gins(AMOVBU, &nz, &dst); p = gins(AMOVBU, &nz, &dst);
p->to.type = D_OREG; p->to.type = D_OREG;
p->to.offset = 1; p->to.offset = 1;
p->scond |= C_PBIT; p->scond |= C_PBIT;
......
...@@ -141,6 +141,10 @@ zaddr(Biobuf *b, Addr *a, int s) ...@@ -141,6 +141,10 @@ zaddr(Biobuf *b, Addr *a, int s)
} }
break; break;
case D_REGREG:
Bputc(b, a->offset);
break;
case D_FCONST: case D_FCONST:
fatal("zaddr D_FCONST not implemented"); fatal("zaddr D_FCONST not implemented");
//ieeedtod(&e, a->dval); //ieeedtod(&e, a->dval);
......
This diff is collapsed.
...@@ -77,8 +77,10 @@ int ...@@ -77,8 +77,10 @@ int
Dconv(Fmt *fp) Dconv(Fmt *fp)
{ {
char str[100]; //, s[100]; char str[100]; //, s[100];
char *op;
Addr *a; Addr *a;
int i; int i;
int32 v;
// uint32 d1, d2; // uint32 d1, d2;
a = va_arg(fp->args, Addr*); a = va_arg(fp->args, Addr*);
...@@ -111,6 +113,17 @@ Dconv(Fmt *fp) ...@@ -111,6 +113,17 @@ Dconv(Fmt *fp)
sprint(str, "$%d-%d", a->offset, a->offset2); sprint(str, "$%d-%d", a->offset, a->offset2);
break; break;
case D_SHIFT:
v = a->offset;
op = "<<>>->@>" + (((v>>5) & 3) << 1);
if(v & (1<<4))
sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
else
sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
if(a->reg != NREG)
sprint(str+strlen(str), "(R%d)", a->reg);
break;
case D_FCONST: case D_FCONST:
snprint(str, sizeof(str), "$(%.17e)", a->dval); snprint(str, sizeof(str), "$(%.17e)", a->dval);
break; break;
......
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