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