Commit e81d97ea authored by Russ Cox's avatar Russ Cox

clean up gmove:

	* conversions all in one place.
	* no separate load, store phases;
	  direct memory addressing when possible
	  (this is the x86 after all!).
	  avoids extra registers, extra MOVQs.
	* fixes int32 -> uint64 bug
	  (was zero-extending)

R=ken
OCL=29482
CL=29484
parent b3f303ec
...@@ -201,8 +201,14 @@ cgen(Node *n, Node *res) ...@@ -201,8 +201,14 @@ cgen(Node *n, Node *res)
break; break;
} }
regalloc(&n1, nl->type, res); regalloc(&n1, nl->type, res);
regalloc(&n2, n->type, &n1);
cgen(nl, &n1); cgen(nl, &n1);
gmove(&n1, res); // if we do the conversion n1 -> n2 here
// reusing the register, then gmove won't
// have to allocate its own register.
gmove(&n1, &n2);
gmove(&n2, res);
regfree(&n2);
regfree(&n1); regfree(&n1);
break; break;
......
...@@ -491,8 +491,10 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx) ...@@ -491,8 +491,10 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
t = types[TUINT32]; t = types[TUINT32];
} }
a = optoas(op, t); a = optoas(op, t);
ax->type = t;
dx->type = t;
regalloc(&n3, nr->type, N); regalloc(&n3, t, N);
if(nl->ullman >= nr->ullman) { if(nl->ullman >= nr->ullman) {
cgen(nl, ax); cgen(nl, ax);
if(!issigned[t->etype]) { if(!issigned[t->etype]) {
......
This diff is collapsed.
...@@ -801,3 +801,95 @@ nonnegconst(Node *n) ...@@ -801,3 +801,95 @@ nonnegconst(Node *n)
} }
return -1; return -1;
} }
/*
* convert x to type et and back to int64
* for sign extension and truncation.
*/
int64
iconv(int64 x, int et)
{
switch(et) {
case TINT8:
x = (int8)x;
break;
case TUINT8:
x = (uint8)x;
break;
case TINT16:
x = (int16)x;
break;
case TUINT16:
x = (uint64)x;
break;
case TINT32:
x = (int32)x;
break;
case TUINT32:
x = (uint32)x;
break;
case TINT64:
case TUINT64:
break;
}
return x;
}
/*
* convert constant val to type t; leave in con.
* for back end.
*/
void
convconst(Node *con, Type *t, Val *val)
{
int64 i;
int tt;
tt = simsimtype(t);
// copy the constant for conversion
nodconst(con, types[TINT8], 0);
con->type = t;
con->val = *val;
if(isint[tt]) {
con->val.ctype = CTINT;
con->val.u.xval = mal(sizeof *con->val.u.xval);
switch(val->ctype) {
default:
fatal("convconst ctype=%d %lT", val->ctype, t->type);
case CTINT:
i = mpgetfix(val->u.xval);
break;
case CTBOOL:
i = val->u.bval;
break;
case CTNIL:
i = 0;
break;
}
i = iconv(i, tt);
mpmovecfix(con->val.u.xval, i);
return;
}
if(isfloat[tt]) {
if(con->val.ctype == CTINT) {
con->val.ctype = CTFLT;
con->val.u.fval = mal(sizeof *con->val.u.fval);
mpmovefixflt(con->val.u.fval, val->u.xval);
}
if(con->val.ctype != CTFLT)
fatal("convconst ctype=%d %T", con->val.ctype, t);
if(!isfloat[tt]) {
// easy to handle, but can it happen?
fatal("convconst CTINT %T", t);
}
if(tt == TFLOAT32)
con->val.u.fval = truncfltlit(con->val.u.fval, t);
return;
}
fatal("convconst %lT constant", t);
}
...@@ -1061,7 +1061,7 @@ addconst(Node *n, Node *e, int ctxt) ...@@ -1061,7 +1061,7 @@ addconst(Node *n, Node *e, int ctxt)
d = dcl(); d = dcl();
d->dsym = s; d->dsym = s;
d->dnode = e; d->dnode = e;
d->op = OCONST; d->op = OLITERAL;
d->back = r->back; d->back = r->back;
r->back->forw = d; r->back->forw = d;
r->back = d; r->back = d;
......
...@@ -298,7 +298,7 @@ enum ...@@ -298,7 +298,7 @@ enum
{ {
OXXX, OXXX,
OTYPE, OCONST, OVAR, OIMPORT, OTYPE, OVAR, OIMPORT,
ONAME, ONONAME, ODCL, ONAME, ONONAME, ODCL,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, ODOT, ODOTPTR, ODOTMETH, ODOTINTER,
...@@ -315,7 +315,7 @@ enum ...@@ -315,7 +315,7 @@ enum
OEQ, ONE, OLT, OLE, OGE, OGT, OEQ, ONE, OLT, OLE, OGE, OGT,
OADD, OSUB, OOR, OXOR, OADD, OSUB, OOR, OXOR,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT, OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT,
OINC, ODEC, // placeholders - not used OINC, ODEC,
OFUNC, OFUNC,
OLABEL, OLABEL,
OBREAK, OBREAK,
...@@ -795,6 +795,8 @@ Node* adddot(Node*); ...@@ -795,6 +795,8 @@ Node* adddot(Node*);
void expandmeth(Sym*, Type*); void expandmeth(Sym*, Type*);
void genwrapper(Type*, Type*, Sym*); void genwrapper(Type*, Type*, Sym*);
int simsimtype(Type*);
/* /*
* dcl.c * dcl.c
*/ */
...@@ -949,6 +951,8 @@ int smallintconst(Node*); ...@@ -949,6 +951,8 @@ int smallintconst(Node*);
long nonnegconst(Node*); long nonnegconst(Node*);
int consttype(Node*); int consttype(Node*);
int isconst(Node*, int); int isconst(Node*, int);
Mpflt* truncfltlit(Mpflt*, Type*);
void convconst(Node*, Type*, Val*);
/* /*
* align.c * align.c
......
...@@ -671,7 +671,6 @@ opnames[] = ...@@ -671,7 +671,6 @@ opnames[] =
[OCOMPOS] = "COMPOS", [OCOMPOS] = "COMPOS",
[OCOMPSLICE] = "COMPSLICE", [OCOMPSLICE] = "COMPSLICE",
[OCOM] = "COM", [OCOM] = "COM",
[OCONST] = "CONST",
[OCONTINUE] = "CONTINUE", [OCONTINUE] = "CONTINUE",
[OCONV] = "CONV", [OCONV] = "CONV",
[ODCLARG] = "DCLARG", [ODCLARG] = "DCLARG",
...@@ -3015,3 +3014,29 @@ runifacechecks(void) ...@@ -3015,3 +3014,29 @@ runifacechecks(void)
} }
lineno = lno; lineno = lno;
} }
/*
* even simpler simtype; get rid of ptr, bool.
* assuming that the front end has rejected
* all the invalid conversions (like ptr -> bool)
*/
int
simsimtype(Type *t)
{
int et;
et = simtype[t->etype];
switch(et) {
case TPTR32:
et = TUINT32;
break;
case TPTR64:
et = TUINT64;
break;
case TBOOL:
et = TUINT8;
break;
}
return et;
}
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