Commit d30285a6 authored by Russ Cox's avatar Russ Cox

move some portable pieces of 6g/gsubr.c into gc/subr.c

	int	brcom(int);
	int	brrev(int);
	void	setmaxarg(Type*);
	Sig*	lsort(Sig*, int(*)(Sig*, Sig*));
	int	dotoffset(Node*, int*, Node**);
	void	stringpool(Node*);
	void	tempname(Node*, Type*);

R=ken
OCL=26922
CL=26922
parent e5ba266e
......@@ -53,24 +53,6 @@ struct Plist
Plist* link;
};
typedef struct Sig Sig;
struct Sig
{
char* name;
Sym* sym;
uint32 hash;
int32 perm;
int32 offset;
Sig* link;
};
typedef struct Pool Pool;
struct Pool
{
String* sval;
Pool* link;
};
typedef struct Label Label;
struct Label
{
......@@ -89,15 +71,9 @@ EXTERN Prog* pc;
EXTERN Prog* firstpc;
EXTERN Plist* plist;
EXTERN Plist* plast;
EXTERN Pool* poolist;
EXTERN Pool* poolast;
EXTERN Biobuf* bout;
EXTERN int32 dynloc;
EXTERN uchar reg[D_NONE];
EXTERN int32 maxround;
EXTERN int32 widthptr;
EXTERN Sym* symstringo; // string objects
EXTERN int32 stringo; // size of string objects
EXTERN int32 pcloc; // instruction counter
EXTERN String emptystring;
extern char* anames[];
......@@ -164,10 +140,7 @@ void gaddoffset(Node*);
void gconv(int, int);
int conv2pt(Type*);
vlong convvtox(vlong, int);
int brcom(int);
int brrev(int);
void fnparam(Type*, int, int);
Sig* lsort(Sig*, int(*)(Sig*, Sig*));
Prog* gop(int, Node*, Node*, Node*);
void setconst(Addr*, vlong);
void setaddr(Addr*, Node*);
......@@ -182,11 +155,8 @@ void nodindreg(Node*, Type*, int);
void nodconst(Node*, Type*, vlong);
void gconreg(int, vlong, int);
void buildtxt(void);
void stringpool(Node*);
void tempname(Node*, Type*);
Plist* newplist(void);
int isfat(Type*);
void setmaxarg(Type*);
void sudoclean(void);
int sudoaddable(Node*, Addr*);
void afunclit(Addr*);
......
......@@ -320,26 +320,6 @@ fatal("shouldnt be used");
return n;
}
void
nodconst(Node *n, Type *t, vlong v)
{
memset(n, 0, sizeof(*n));
n->op = OLITERAL;
n->addable = 1;
ullmancalc(n);
n->val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(n->val.u.xval, v);
n->val.ctype = CTINT;
n->type = t;
switch(t->etype) {
case TFLOAT32:
case TFLOAT64:
case TFLOAT80:
fatal("nodconst: bad type %T", t);
}
}
/*
* generate
* as $c, reg
......@@ -1698,230 +1678,6 @@ isfat(Type *t)
return 0;
}
/*
* return !(op)
* eg == <=> !=
*/
int
brcom(int a)
{
switch(a) {
case OEQ: return ONE;
case ONE: return OEQ;
case OLT: return OGE;
case OGT: return OLE;
case OLE: return OGT;
case OGE: return OLT;
}
fatal("brcom: no com for %A\n", a);
return a;
}
/*
* return reverse(op)
* eg a op b <=> b r(op) a
*/
int
brrev(int a)
{
switch(a) {
case OEQ: return OEQ;
case ONE: return ONE;
case OLT: return OGT;
case OGT: return OLT;
case OLE: return OGE;
case OGE: return OLE;
}
fatal("brcom: no rev for %A\n", a);
return a;
}
/*
* make a new off the books
*/
void
tempname(Node *n, Type *t)
{
Sym *s;
uint32 w;
if(t == T) {
yyerror("tempname called with nil type");
t = types[TINT32];
}
s = lookup("!tmpname!");
memset(n, 0, sizeof(*n));
n->op = ONAME;
n->sym = s;
n->type = t;
n->etype = t->etype;
n->class = PAUTO;
n->addable = 1;
n->ullman = 1;
n->noescape = 1;
dowidth(t);
w = t->width;
stksize += w;
stksize = rnd(stksize, w);
n->xoffset = -stksize;
}
void
stringpool(Node *n)
{
Pool *p;
int w;
if(n->op != OLITERAL || n->val.ctype != CTSTR) {
if(n->val.ctype == CTNIL)
return;
fatal("stringpool: not string %N", n);
}
p = mal(sizeof(*p));
p->sval = n->val.u.sval;
p->link = nil;
if(poolist == nil)
poolist = p;
else
poolast->link = p;
poolast = p;
w = types[TINT32]->width;
symstringo->offset += w; // len
symstringo->offset += p->sval->len; // str[len]
symstringo->offset = rnd(symstringo->offset, w);
}
Sig*
lsort(Sig *l, int(*f)(Sig*, Sig*))
{
Sig *l1, *l2, *le;
if(l == 0 || l->link == 0)
return l;
l1 = l;
l2 = l;
for(;;) {
l2 = l2->link;
if(l2 == 0)
break;
l2 = l2->link;
if(l2 == 0)
break;
l1 = l1->link;
}
l2 = l1->link;
l1->link = 0;
l1 = lsort(l, f);
l2 = lsort(l2, f);
/* set up lead element */
if((*f)(l1, l2) < 0) {
l = l1;
l1 = l1->link;
} else {
l = l2;
l2 = l2->link;
}
le = l;
for(;;) {
if(l1 == 0) {
while(l2) {
le->link = l2;
le = l2;
l2 = l2->link;
}
le->link = 0;
break;
}
if(l2 == 0) {
while(l1) {
le->link = l1;
le = l1;
l1 = l1->link;
}
break;
}
if((*f)(l1, l2) < 0) {
le->link = l1;
le = l1;
l1 = l1->link;
} else {
le->link = l2;
le = l2;
l2 = l2->link;
}
}
le->link = 0;
return l;
}
void
setmaxarg(Type *t)
{
int32 w;
w = t->argwid;
if(w > maxarg)
maxarg = w;
}
/*
* gather series of offsets
* >=0 is direct addressed field
* <0 is pointer to next field (+1)
*/
int
dotoffset(Node *n, int *oary, Node **nn)
{
int i;
switch(n->op) {
case ODOT:
if(n->xoffset == BADWIDTH) {
dump("bad width in dotoffset", n);
fatal("bad width in dotoffset");
}
i = dotoffset(n->left, oary, nn);
if(i > 0) {
if(oary[i-1] >= 0)
oary[i-1] += n->xoffset;
else
oary[i-1] -= n->xoffset;
break;
}
if(i < 10)
oary[i++] = n->xoffset;
break;
case ODOTPTR:
if(n->xoffset == BADWIDTH) {
dump("bad width in dotoffset", n);
fatal("bad width in dotoffset");
}
i = dotoffset(n->left, oary, nn);
if(i < 10)
oary[i++] = -(n->xoffset+1);
break;
default:
*nn = n;
return 0;
}
if(i >= 10)
*nn = N;
return i;
}
enum
{
ODynam = 1<<0,
......
......@@ -452,6 +452,29 @@ struct Typedef
extern Typedef typedefs[];
typedef struct Sig Sig;
struct Sig
{
char* name;
Sym* sym;
uint32 hash;
int32 perm;
int32 offset;
Sig* link;
};
typedef struct Pool Pool;
struct Pool
{
String* sval;
Pool* link;
};
EXTERN Pool* poolist;
EXTERN Pool* poolast;
EXTERN Sym* symstringo; // string objects
EXTERN int32 stringo; // size of string objects
typedef struct Io Io;
struct Io
{
......@@ -712,6 +735,7 @@ uint32 typehash(Type*, int, int);
void frame(int);
Node* dobad(void);
Node* nodintconst(int64);
void nodconst(Node*, Type*, int64);
Node* nodnil(void);
Node* nodbool(int);
void ullmancalc(Node*);
......@@ -740,6 +764,14 @@ Type* structnext(Iter*);
Type* funcfirst(Iter*, Type*);
Type* funcnext(Iter*);
int brcom(int);
int brrev(int);
void setmaxarg(Type*);
Sig* lsort(Sig*, int(*)(Sig*, Sig*));
int dotoffset(Node*, int*, Node**);
void stringpool(Node*);
void tempname(Node*, Type*);
int Econv(Fmt*);
int Jconv(Fmt*);
int Lconv(Fmt*);
......@@ -917,7 +949,6 @@ void dumpobj(void);
void dowidth(Type*);
void argspace(int32);
Node* nodarg(Type*, int);
void nodconst(Node*, Type*, vlong);
Type* deep(Type*);
Type* shallow(Type*);
......
......@@ -365,6 +365,22 @@ nodintconst(int64 v)
return c;
}
void
nodconst(Node *n, Type *t, int64 v)
{
memset(n, 0, sizeof(*n));
n->op = OLITERAL;
n->addable = 1;
ullmancalc(n);
n->val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(n->val.u.xval, v);
n->val.ctype = CTINT;
n->type = t;
if(isfloat[t->etype])
fatal("nodconst: bad type %T", t);
}
Node*
nodnil(void)
{
......@@ -2316,6 +2332,230 @@ getinargx(Type *t)
return *getinarg(t);
}
/*
* return !(op)
* eg == <=> !=
*/
int
brcom(int a)
{
switch(a) {
case OEQ: return ONE;
case ONE: return OEQ;
case OLT: return OGE;
case OGT: return OLE;
case OLE: return OGT;
case OGE: return OLT;
}
fatal("brcom: no com for %A\n", a);
return a;
}
/*
* return reverse(op)
* eg a op b <=> b r(op) a
*/
int
brrev(int a)
{
switch(a) {
case OEQ: return OEQ;
case ONE: return ONE;
case OLT: return OGT;
case OGT: return OLT;
case OLE: return OGE;
case OGE: return OLE;
}
fatal("brcom: no rev for %A\n", a);
return a;
}
/*
* make a new off the books
*/
void
tempname(Node *n, Type *t)
{
Sym *s;
uint32 w;
if(t == T) {
yyerror("tempname called with nil type");
t = types[TINT32];
}
s = lookup("!tmpname!");
memset(n, 0, sizeof(*n));
n->op = ONAME;
n->sym = s;
n->type = t;
n->etype = t->etype;
n->class = PAUTO;
n->addable = 1;
n->ullman = 1;
n->noescape = 1;
dowidth(t);
w = t->width;
stksize += w;
stksize = rnd(stksize, w);
n->xoffset = -stksize;
}
void
stringpool(Node *n)
{
Pool *p;
int w;
if(n->op != OLITERAL || n->val.ctype != CTSTR) {
if(n->val.ctype == CTNIL)
return;
fatal("stringpool: not string %N", n);
}
p = mal(sizeof(*p));
p->sval = n->val.u.sval;
p->link = nil;
if(poolist == nil)
poolist = p;
else
poolast->link = p;
poolast = p;
w = types[TINT32]->width;
symstringo->offset += w; // len
symstringo->offset += p->sval->len; // str[len]
symstringo->offset = rnd(symstringo->offset, w);
}
Sig*
lsort(Sig *l, int(*f)(Sig*, Sig*))
{
Sig *l1, *l2, *le;
if(l == 0 || l->link == 0)
return l;
l1 = l;
l2 = l;
for(;;) {
l2 = l2->link;
if(l2 == 0)
break;
l2 = l2->link;
if(l2 == 0)
break;
l1 = l1->link;
}
l2 = l1->link;
l1->link = 0;
l1 = lsort(l, f);
l2 = lsort(l2, f);
/* set up lead element */
if((*f)(l1, l2) < 0) {
l = l1;
l1 = l1->link;
} else {
l = l2;
l2 = l2->link;
}
le = l;
for(;;) {
if(l1 == 0) {
while(l2) {
le->link = l2;
le = l2;
l2 = l2->link;
}
le->link = 0;
break;
}
if(l2 == 0) {
while(l1) {
le->link = l1;
le = l1;
l1 = l1->link;
}
break;
}
if((*f)(l1, l2) < 0) {
le->link = l1;
le = l1;
l1 = l1->link;
} else {
le->link = l2;
le = l2;
l2 = l2->link;
}
}
le->link = 0;
return l;
}
void
setmaxarg(Type *t)
{
int32 w;
w = t->argwid;
if(w > maxarg)
maxarg = w;
}
/*
* gather series of offsets
* >=0 is direct addressed field
* <0 is pointer to next field (+1)
*/
int
dotoffset(Node *n, int *oary, Node **nn)
{
int i;
switch(n->op) {
case ODOT:
if(n->xoffset == BADWIDTH) {
dump("bad width in dotoffset", n);
fatal("bad width in dotoffset");
}
i = dotoffset(n->left, oary, nn);
if(i > 0) {
if(oary[i-1] >= 0)
oary[i-1] += n->xoffset;
else
oary[i-1] -= n->xoffset;
break;
}
if(i < 10)
oary[i++] = n->xoffset;
break;
case ODOTPTR:
if(n->xoffset == BADWIDTH) {
dump("bad width in dotoffset", n);
fatal("bad width in dotoffset");
}
i = dotoffset(n->left, oary, nn);
if(i < 10)
oary[i++] = -(n->xoffset+1);
break;
default:
*nn = n;
return 0;
}
if(i >= 10)
*nn = N;
return i;
}
/*
* code to resolve elided DOTs
* in embedded types
......
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