mirror of
https://github.com/golang/go
synced 2024-11-26 17:07:09 -07:00
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
This commit is contained in:
parent
e5ba266e93
commit
d30285a6f5
@ -53,24 +53,6 @@ struct Plist
|
|||||||
Plist* link;
|
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;
|
typedef struct Label Label;
|
||||||
struct Label
|
struct Label
|
||||||
{
|
{
|
||||||
@ -89,15 +71,9 @@ EXTERN Prog* pc;
|
|||||||
EXTERN Prog* firstpc;
|
EXTERN Prog* firstpc;
|
||||||
EXTERN Plist* plist;
|
EXTERN Plist* plist;
|
||||||
EXTERN Plist* plast;
|
EXTERN Plist* plast;
|
||||||
EXTERN Pool* poolist;
|
|
||||||
EXTERN Pool* poolast;
|
|
||||||
EXTERN Biobuf* bout;
|
EXTERN Biobuf* bout;
|
||||||
EXTERN int32 dynloc;
|
EXTERN int32 dynloc;
|
||||||
EXTERN uchar reg[D_NONE];
|
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 int32 pcloc; // instruction counter
|
||||||
EXTERN String emptystring;
|
EXTERN String emptystring;
|
||||||
extern char* anames[];
|
extern char* anames[];
|
||||||
@ -164,10 +140,7 @@ void gaddoffset(Node*);
|
|||||||
void gconv(int, int);
|
void gconv(int, int);
|
||||||
int conv2pt(Type*);
|
int conv2pt(Type*);
|
||||||
vlong convvtox(vlong, int);
|
vlong convvtox(vlong, int);
|
||||||
int brcom(int);
|
|
||||||
int brrev(int);
|
|
||||||
void fnparam(Type*, int, int);
|
void fnparam(Type*, int, int);
|
||||||
Sig* lsort(Sig*, int(*)(Sig*, Sig*));
|
|
||||||
Prog* gop(int, Node*, Node*, Node*);
|
Prog* gop(int, Node*, Node*, Node*);
|
||||||
void setconst(Addr*, vlong);
|
void setconst(Addr*, vlong);
|
||||||
void setaddr(Addr*, Node*);
|
void setaddr(Addr*, Node*);
|
||||||
@ -182,11 +155,8 @@ void nodindreg(Node*, Type*, int);
|
|||||||
void nodconst(Node*, Type*, vlong);
|
void nodconst(Node*, Type*, vlong);
|
||||||
void gconreg(int, vlong, int);
|
void gconreg(int, vlong, int);
|
||||||
void buildtxt(void);
|
void buildtxt(void);
|
||||||
void stringpool(Node*);
|
|
||||||
void tempname(Node*, Type*);
|
|
||||||
Plist* newplist(void);
|
Plist* newplist(void);
|
||||||
int isfat(Type*);
|
int isfat(Type*);
|
||||||
void setmaxarg(Type*);
|
|
||||||
void sudoclean(void);
|
void sudoclean(void);
|
||||||
int sudoaddable(Node*, Addr*);
|
int sudoaddable(Node*, Addr*);
|
||||||
void afunclit(Addr*);
|
void afunclit(Addr*);
|
||||||
|
@ -320,26 +320,6 @@ fatal("shouldnt be used");
|
|||||||
return n;
|
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
|
* generate
|
||||||
* as $c, reg
|
* as $c, reg
|
||||||
@ -1698,230 +1678,6 @@ isfat(Type *t)
|
|||||||
return 0;
|
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
|
enum
|
||||||
{
|
{
|
||||||
ODynam = 1<<0,
|
ODynam = 1<<0,
|
||||||
|
@ -452,6 +452,29 @@ struct Typedef
|
|||||||
|
|
||||||
extern Typedef typedefs[];
|
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;
|
typedef struct Io Io;
|
||||||
struct Io
|
struct Io
|
||||||
{
|
{
|
||||||
@ -712,6 +735,7 @@ uint32 typehash(Type*, int, int);
|
|||||||
void frame(int);
|
void frame(int);
|
||||||
Node* dobad(void);
|
Node* dobad(void);
|
||||||
Node* nodintconst(int64);
|
Node* nodintconst(int64);
|
||||||
|
void nodconst(Node*, Type*, int64);
|
||||||
Node* nodnil(void);
|
Node* nodnil(void);
|
||||||
Node* nodbool(int);
|
Node* nodbool(int);
|
||||||
void ullmancalc(Node*);
|
void ullmancalc(Node*);
|
||||||
@ -740,6 +764,14 @@ Type* structnext(Iter*);
|
|||||||
Type* funcfirst(Iter*, Type*);
|
Type* funcfirst(Iter*, Type*);
|
||||||
Type* funcnext(Iter*);
|
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 Econv(Fmt*);
|
||||||
int Jconv(Fmt*);
|
int Jconv(Fmt*);
|
||||||
int Lconv(Fmt*);
|
int Lconv(Fmt*);
|
||||||
@ -917,7 +949,6 @@ void dumpobj(void);
|
|||||||
void dowidth(Type*);
|
void dowidth(Type*);
|
||||||
void argspace(int32);
|
void argspace(int32);
|
||||||
Node* nodarg(Type*, int);
|
Node* nodarg(Type*, int);
|
||||||
void nodconst(Node*, Type*, vlong);
|
|
||||||
Type* deep(Type*);
|
Type* deep(Type*);
|
||||||
Type* shallow(Type*);
|
Type* shallow(Type*);
|
||||||
|
|
||||||
|
@ -365,6 +365,22 @@ nodintconst(int64 v)
|
|||||||
return c;
|
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*
|
Node*
|
||||||
nodnil(void)
|
nodnil(void)
|
||||||
{
|
{
|
||||||
@ -2316,6 +2332,230 @@ getinargx(Type *t)
|
|||||||
return *getinarg(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
|
* code to resolve elided DOTs
|
||||||
* in embedded types
|
* in embedded types
|
||||||
|
Loading…
Reference in New Issue
Block a user