mirror of
https://github.com/golang/go
synced 2024-11-25 14:17:57 -07:00
move 6c/pgen.c, 6c/pswt.c into cc
and make 5c, 8c use them. centralizes reachability analysis and switch generation. now 8c doesn't have spurious warnings in pkg/runtime. R=ken OCL=31266 CL=31266
This commit is contained in:
parent
8afeb52cac
commit
27432d67ec
@ -21,6 +21,8 @@ OFILES=\
|
||||
mul.$O\
|
||||
reg.$O\
|
||||
peep.$O\
|
||||
pgen.$O\
|
||||
pswt.$O\
|
||||
../5l/enam.$O\
|
||||
|
||||
LIB=\
|
||||
@ -36,3 +38,7 @@ clean:
|
||||
|
||||
install: $(TARG)
|
||||
cp $(TARG) $(BIN)/$(TARG)
|
||||
|
||||
%.$O: ../cc/%.c
|
||||
$(CC) $(CFLAGS) -c -I. -o $@ ../cc/$*.c
|
||||
|
||||
|
@ -28,10 +28,11 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
void
|
||||
cgen(Node *n, Node *nn, int inrel)
|
||||
_cgen(Node *n, Node *nn, int inrel)
|
||||
{
|
||||
Node *l, *r;
|
||||
Prog *p1;
|
||||
@ -75,7 +76,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
switch(o) {
|
||||
default:
|
||||
regret(&nod, r);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
|
||||
regsalloc(&nod1, r);
|
||||
gopcode(OAS, &nod, Z, &nod1);
|
||||
@ -83,7 +84,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
regfree(&nod);
|
||||
nod = *n;
|
||||
nod.right = &nod1;
|
||||
cgen(&nod, nn, 0);
|
||||
cgen(&nod, nn);
|
||||
return;
|
||||
|
||||
case OFUNC:
|
||||
@ -109,7 +110,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
regret(&nod, r);
|
||||
else
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
gmove(&nod, l);
|
||||
if(nn != Z)
|
||||
gmove(&nod, nn);
|
||||
@ -128,10 +129,10 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
break;
|
||||
}
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
} else {
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
reglcgen(&nod1, l, Z);
|
||||
}
|
||||
gmove(&nod, &nod1);
|
||||
@ -144,9 +145,9 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
regalloc(&nod, r, nn);
|
||||
if(l->complex >= r->complex) {
|
||||
reglcgen(&nod1, n, Z);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
} else {
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
reglcgen(&nod1, n, Z);
|
||||
}
|
||||
regalloc(&nod2, n, Z);
|
||||
@ -169,7 +170,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
if(nn != Z)
|
||||
if((t = vlog(r)) >= 0) {
|
||||
/* signed div/mod by constant power of 2 */
|
||||
cgen(l, nn, 0);
|
||||
cgen(l, nn);
|
||||
gopcode(OGE, nodconst(0), nn, Z);
|
||||
p1 = p;
|
||||
if(o == ODIV) {
|
||||
@ -194,7 +195,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
if(nn != Z)
|
||||
if(l->op == OCONST)
|
||||
if(!typefd[n->type->etype]) {
|
||||
cgen(r, nn, 0);
|
||||
cgen(r, nn);
|
||||
gopcode(o, Z, l, nn);
|
||||
break;
|
||||
}
|
||||
@ -211,7 +212,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
if(nn != Z)
|
||||
if(r->op == OCONST)
|
||||
if(!typefd[n->type->etype]) {
|
||||
cgen(l, nn, 0);
|
||||
cgen(l, nn);
|
||||
if(r->vconst == 0)
|
||||
if(o != OAND)
|
||||
break;
|
||||
@ -235,15 +236,15 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
}
|
||||
if(l->complex >= r->complex) {
|
||||
regalloc(&nod, l, nn);
|
||||
cgen(l, &nod, 0);
|
||||
cgen(l, &nod);
|
||||
regalloc(&nod1, r, Z);
|
||||
cgen(r, &nod1, 0);
|
||||
cgen(r, &nod1);
|
||||
gopcode(o, &nod1, Z, &nod);
|
||||
} else {
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 0);
|
||||
cgen(r, &nod);
|
||||
regalloc(&nod1, l, Z);
|
||||
cgen(l, &nod1, 0);
|
||||
cgen(l, &nod1);
|
||||
gopcode(o, &nod, &nod1, &nod);
|
||||
}
|
||||
gopcode(OAS, &nod, Z, nn);
|
||||
@ -293,10 +294,10 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
else
|
||||
nod2 = *l;
|
||||
regalloc(&nod1, r, Z);
|
||||
cgen(r, &nod1, 0);
|
||||
cgen(r, &nod1);
|
||||
} else {
|
||||
regalloc(&nod1, r, Z);
|
||||
cgen(r, &nod1, 0);
|
||||
cgen(r, &nod1);
|
||||
if(l->addable < INDEXED)
|
||||
reglcgen(&nod2, l, Z);
|
||||
else
|
||||
@ -320,10 +321,10 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
if(l->complex >= r->complex) {
|
||||
bitload(l, &nod, &nod1, &nod2, &nod4);
|
||||
regalloc(&nod3, r, Z);
|
||||
cgen(r, &nod3, 0);
|
||||
cgen(r, &nod3);
|
||||
} else {
|
||||
regalloc(&nod3, r, Z);
|
||||
cgen(r, &nod3, 0);
|
||||
cgen(r, &nod3);
|
||||
bitload(l, &nod, &nod1, &nod2, &nod4);
|
||||
}
|
||||
gmove(&nod, &nod4);
|
||||
@ -348,7 +349,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
diag(n, "bad function call");
|
||||
|
||||
regret(&nod, l->left);
|
||||
cgen(l->left, &nod, 0);
|
||||
cgen(l->left, &nod);
|
||||
regsalloc(&nod1, l->left);
|
||||
gopcode(OAS, &nod, Z, &nod1);
|
||||
regfree(&nod);
|
||||
@ -358,7 +359,7 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
nod2 = *l;
|
||||
nod2.left = &nod1;
|
||||
nod2.complex = 1;
|
||||
cgen(&nod, nn, 0);
|
||||
cgen(&nod, nn);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -393,11 +394,11 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) {
|
||||
v = r->vconst;
|
||||
r->vconst = 0;
|
||||
cgen(l, &nod, 0);
|
||||
cgen(l, &nod);
|
||||
nod.xoffset += v;
|
||||
r->vconst = v;
|
||||
} else
|
||||
cgen(l, &nod, 0);
|
||||
cgen(l, &nod);
|
||||
regind(&nod, n);
|
||||
gopcode(OAS, &nod, Z, nn);
|
||||
regfree(&nod);
|
||||
@ -436,8 +437,8 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
break;
|
||||
|
||||
case OCOMMA:
|
||||
cgen(l, Z, 0);
|
||||
cgen(r, nn, 0);
|
||||
cgen(l, Z);
|
||||
cgen(r, nn);
|
||||
break;
|
||||
|
||||
case OCAST:
|
||||
@ -450,12 +451,12 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
*/
|
||||
if(nocast(l->type, n->type)) {
|
||||
if(nocast(n->type, nn->type)) {
|
||||
cgen(l, nn, 0);
|
||||
cgen(l, nn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
regalloc(&nod, l, nn);
|
||||
cgen(l, &nod, 0);
|
||||
cgen(l, &nod);
|
||||
regalloc(&nod1, n, &nod);
|
||||
if(inrel)
|
||||
gmover(&nod, &nod1);
|
||||
@ -477,18 +478,18 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
}
|
||||
nod.xoffset += (int32)r->vconst;
|
||||
nod.type = n->type;
|
||||
cgen(&nod, nn, 0);
|
||||
cgen(&nod, nn);
|
||||
}
|
||||
break;
|
||||
|
||||
case OCOND:
|
||||
bcgen(l, 1);
|
||||
p1 = p;
|
||||
cgen(r->left, nn, 0);
|
||||
cgen(r->left, nn);
|
||||
gbranch(OGOTO);
|
||||
patch(p1, pc);
|
||||
p1 = p;
|
||||
cgen(r->right, nn, 0);
|
||||
cgen(r->right, nn);
|
||||
patch(p1, pc);
|
||||
break;
|
||||
|
||||
@ -586,6 +587,18 @@ cgen(Node *n, Node *nn, int inrel)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
cgen(Node *n, Node *nn)
|
||||
{
|
||||
_cgen(n, nn, 0);
|
||||
}
|
||||
|
||||
void
|
||||
cgenrel(Node *n, Node *nn)
|
||||
{
|
||||
_cgen(n, nn, 1);
|
||||
}
|
||||
|
||||
void
|
||||
reglcgen(Node *t, Node *n, Node *nn)
|
||||
{
|
||||
@ -609,7 +622,7 @@ reglcgen(Node *t, Node *n, Node *nn)
|
||||
} else if(n->op == OINDREG) {
|
||||
if((v = n->xoffset) > -4096 && v < 4096) {
|
||||
n->op = OREGISTER;
|
||||
cgen(n, t, 0);
|
||||
cgen(n, t);
|
||||
t->xoffset += v;
|
||||
n->op = OINDREG;
|
||||
regind(t, n);
|
||||
@ -668,12 +681,12 @@ lcgen(Node *n, Node *nn)
|
||||
break;
|
||||
|
||||
case OCOMMA:
|
||||
cgen(n->left, n->left, 0);
|
||||
cgen(n->left, n->left);
|
||||
lcgen(n->right, nn);
|
||||
break;
|
||||
|
||||
case OIND:
|
||||
cgen(n->left, nn, 0);
|
||||
cgen(n->left, nn);
|
||||
break;
|
||||
|
||||
case OCOND:
|
||||
@ -718,7 +731,7 @@ boolgen(Node *n, int true, Node *nn)
|
||||
|
||||
default:
|
||||
regalloc(&nod, n, nn);
|
||||
cgen(n, &nod, 0);
|
||||
cgen(n, &nod);
|
||||
o = ONE;
|
||||
if(true)
|
||||
o = comrel[relindex(o)];
|
||||
@ -742,7 +755,7 @@ boolgen(Node *n, int true, Node *nn)
|
||||
goto com;
|
||||
|
||||
case OCOMMA:
|
||||
cgen(l, Z, 0);
|
||||
cgen(l, Z);
|
||||
boolgen(r, true, nn);
|
||||
break;
|
||||
|
||||
@ -809,7 +822,7 @@ boolgen(Node *n, int true, Node *nn)
|
||||
o = comrel[relindex(o)];
|
||||
if(l->complex >= FNX && r->complex >= FNX) {
|
||||
regret(&nod, r);
|
||||
cgen(r, &nod, 1);
|
||||
cgenrel(r, &nod);
|
||||
regsalloc(&nod1, r);
|
||||
gopcode(OAS, &nod, Z, &nod1);
|
||||
regfree(&nod);
|
||||
@ -820,7 +833,7 @@ boolgen(Node *n, int true, Node *nn)
|
||||
}
|
||||
if(sconst(l)) {
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 1);
|
||||
cgenrel(r, &nod);
|
||||
o = invrel[relindex(o)];
|
||||
gopcode(o, l, &nod, Z);
|
||||
regfree(&nod);
|
||||
@ -828,21 +841,21 @@ boolgen(Node *n, int true, Node *nn)
|
||||
}
|
||||
if(sconst(r)) {
|
||||
regalloc(&nod, l, nn);
|
||||
cgen(l, &nod, 1);
|
||||
cgenrel(l, &nod);
|
||||
gopcode(o, r, &nod, Z);
|
||||
regfree(&nod);
|
||||
goto com;
|
||||
}
|
||||
if(l->complex >= r->complex) {
|
||||
regalloc(&nod1, l, nn);
|
||||
cgen(l, &nod1, 1);
|
||||
cgenrel(l, &nod1);
|
||||
regalloc(&nod, r, Z);
|
||||
cgen(r, &nod, 1);
|
||||
cgenrel(r, &nod);
|
||||
} else {
|
||||
regalloc(&nod, r, nn);
|
||||
cgen(r, &nod, 1);
|
||||
cgenrel(r, &nod);
|
||||
regalloc(&nod1, l, Z);
|
||||
cgen(l, &nod1, 1);
|
||||
cgenrel(l, &nod1);
|
||||
}
|
||||
gopcode(o, &nod, &nod1, Z);
|
||||
regfree(&nod);
|
||||
@ -966,7 +979,7 @@ sugen(Node *n, Node *nn, int32 w)
|
||||
r = r->right;
|
||||
}
|
||||
if(nn == Z) {
|
||||
cgen(l, nn, 0);
|
||||
cgen(l, nn);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -1004,7 +1017,7 @@ sugen(Node *n, Node *nn, int32 w)
|
||||
xcom(&nod0);
|
||||
nod0.addable = 0;
|
||||
|
||||
cgen(&nod0, Z, 0);
|
||||
cgen(&nod0, Z);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1034,7 +1047,7 @@ sugen(Node *n, Node *nn, int32 w)
|
||||
n = new(OFUNC, n->left, new(OLIST, nn, n->right));
|
||||
n->type = types[TVOID];
|
||||
n->left->type = types[TVOID];
|
||||
cgen(n, Z, 0);
|
||||
cgen(n, Z);
|
||||
break;
|
||||
|
||||
case OCOND:
|
||||
@ -1049,7 +1062,7 @@ sugen(Node *n, Node *nn, int32 w)
|
||||
break;
|
||||
|
||||
case OCOMMA:
|
||||
cgen(n->left, Z, 0);
|
||||
cgen(n->left, Z);
|
||||
sugen(n->right, nn, w);
|
||||
break;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "../cc/cc.h"
|
||||
#include "../5l/5.out.h"
|
||||
|
||||
@ -93,6 +94,7 @@ struct Case
|
||||
int32 val;
|
||||
int32 label;
|
||||
char def;
|
||||
char isv;
|
||||
};
|
||||
#define C ((Case*)0)
|
||||
|
||||
@ -165,6 +167,7 @@ struct Rgn
|
||||
};
|
||||
|
||||
EXTERN int32 breakpc;
|
||||
EXTERN int32 nbreak;
|
||||
EXTERN Case* cases;
|
||||
EXTERN Node constnode;
|
||||
EXTERN Node fconstnode;
|
||||
@ -243,17 +246,20 @@ void noretval(int);
|
||||
void usedset(Node*, int);
|
||||
void xcom(Node*);
|
||||
int bcomplex(Node*, Node*);
|
||||
Prog* gtext(Sym*, int32);
|
||||
vlong argsize(void);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
*/
|
||||
void cgen(Node*, Node*, int);
|
||||
void cgen(Node*, Node*);
|
||||
void reglcgen(Node*, Node*, Node*);
|
||||
void lcgen(Node*, Node*);
|
||||
void bcgen(Node*, int);
|
||||
void boolgen(Node*, int, Node*);
|
||||
void sugen(Node*, Node*, int32);
|
||||
void layout(Node*, Node*, int, int, Node*);
|
||||
void cgenrel(Node*, Node*);
|
||||
|
||||
/*
|
||||
* txt.c
|
||||
@ -296,7 +302,7 @@ void gpseudo(int, Sym*, Node*);
|
||||
*/
|
||||
int swcmp(const void*, const void*);
|
||||
void doswit(Node*);
|
||||
void swit1(C1*, int, int32, Node*, Node*);
|
||||
void swit1(C1*, int, int32, Node*);
|
||||
void cas(void);
|
||||
void bitload(Node*, Node*, Node*, Node*, Node*);
|
||||
void bitstore(Node*, Node*, Node*, Node*, Node*);
|
||||
|
@ -28,410 +28,16 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
int32
|
||||
argsize(void)
|
||||
Prog*
|
||||
gtext(Sym *s, int32 stkoff)
|
||||
{
|
||||
Type *t;
|
||||
int32 s;
|
||||
|
||||
//print("t=%T\n", thisfn);
|
||||
s = 0;
|
||||
for(t=thisfn->down; t!=T; t=t->down) {
|
||||
switch(t->etype) {
|
||||
case TVOID:
|
||||
break;
|
||||
case TDOT:
|
||||
s += 64;
|
||||
break;
|
||||
default:
|
||||
s = align(s, t, Aarg1);
|
||||
s = align(s, t, Aarg2);
|
||||
break;
|
||||
}
|
||||
//print(" %d %T\n", s, t);
|
||||
}
|
||||
return (s+7) & ~7;
|
||||
}
|
||||
|
||||
void
|
||||
codgen(Node *n, Node *nn)
|
||||
{
|
||||
Prog *sp;
|
||||
Node *n1, nod, nod1;
|
||||
|
||||
cursafe = 0;
|
||||
curarg = 0;
|
||||
maxargsafe = 0;
|
||||
|
||||
/*
|
||||
* isolate name
|
||||
*/
|
||||
for(n1 = nn;; n1 = n1->left) {
|
||||
if(n1 == Z) {
|
||||
diag(nn, "cant find function name");
|
||||
return;
|
||||
}
|
||||
if(n1->op == ONAME)
|
||||
break;
|
||||
}
|
||||
nearln = nn->lineno;
|
||||
gpseudo(ATEXT, n1->sym, nodconst(stkoff));
|
||||
gpseudo(ATEXT, s, nodconst(stkoff));
|
||||
p->to.type = D_CONST2;
|
||||
p->to.offset2 = argsize();
|
||||
|
||||
sp = p;
|
||||
|
||||
/*
|
||||
* isolate first argument
|
||||
*/
|
||||
if(REGARG >= 0) {
|
||||
if(typesuv[thisfn->link->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nodreg(&nod, &nod1, REGARG);
|
||||
gopcode(OAS, &nod, Z, &nod1);
|
||||
} else
|
||||
if(firstarg && typechlp[firstargtype->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nod1.sym = firstarg;
|
||||
nod1.type = firstargtype;
|
||||
nod1.xoffset = align(0, firstargtype, Aarg1);
|
||||
nod1.etype = firstargtype->etype;
|
||||
nodreg(&nod, &nod1, REGARG);
|
||||
gopcode(OAS, &nod, Z, &nod1);
|
||||
}
|
||||
}
|
||||
|
||||
retok = 0;
|
||||
gen(n);
|
||||
if(!retok)
|
||||
if(thisfn->link->etype != TVOID)
|
||||
warn(Z, "no return at end of function: %s", n1->sym->name);
|
||||
noretval(3);
|
||||
gbranch(ORETURN);
|
||||
|
||||
if(!debug['N'] || debug['R'] || debug['P'])
|
||||
regopt(sp);
|
||||
|
||||
sp->to.offset += maxargsafe;
|
||||
}
|
||||
|
||||
void
|
||||
supgen(Node *n)
|
||||
{
|
||||
int32 spc;
|
||||
Prog *sp;
|
||||
|
||||
if(n == Z)
|
||||
return;
|
||||
suppress++;
|
||||
spc = pc;
|
||||
sp = lastp;
|
||||
gen(n);
|
||||
lastp = sp;
|
||||
pc = spc;
|
||||
sp->link = nil;
|
||||
suppress--;
|
||||
}
|
||||
|
||||
void
|
||||
gen(Node *n)
|
||||
{
|
||||
Node *l, nod;
|
||||
Prog *sp, *spc, *spb;
|
||||
Case *cn;
|
||||
int32 sbc, scc;
|
||||
int o, f;
|
||||
|
||||
loop:
|
||||
if(n == Z)
|
||||
return;
|
||||
nearln = n->lineno;
|
||||
o = n->op;
|
||||
if(debug['G'])
|
||||
if(o != OLIST)
|
||||
print("%L %O\n", nearln, o);
|
||||
|
||||
retok = 0;
|
||||
switch(o) {
|
||||
|
||||
default:
|
||||
complex(n);
|
||||
cgen(n, Z, 0);
|
||||
break;
|
||||
|
||||
case OLIST:
|
||||
gen(n->left);
|
||||
|
||||
rloop:
|
||||
n = n->right;
|
||||
goto loop;
|
||||
|
||||
case ORETURN:
|
||||
retok = 1;
|
||||
complex(n);
|
||||
if(n->type == T)
|
||||
break;
|
||||
l = n->left;
|
||||
if(l == Z) {
|
||||
noretval(3);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
}
|
||||
if(typesuv[n->type->etype]) {
|
||||
sugen(l, nodret, n->type->width);
|
||||
noretval(3);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
}
|
||||
regret(&nod, n);
|
||||
cgen(l, &nod, 0);
|
||||
regfree(&nod);
|
||||
if(typefd[n->type->etype])
|
||||
noretval(1);
|
||||
else
|
||||
noretval(2);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
|
||||
case OLABEL:
|
||||
l = n->left;
|
||||
if(l) {
|
||||
l->pc = pc;
|
||||
if(l->label)
|
||||
patch(l->label, pc);
|
||||
}
|
||||
gbranch(OGOTO); /* prevent self reference in reg */
|
||||
patch(p, pc);
|
||||
goto rloop;
|
||||
|
||||
case OGOTO:
|
||||
retok = 1;
|
||||
n = n->left;
|
||||
if(n == Z)
|
||||
return;
|
||||
if(n->complex == 0) {
|
||||
diag(Z, "label undefined: %s", n->sym->name);
|
||||
return;
|
||||
}
|
||||
if(suppress)
|
||||
return;
|
||||
gbranch(OGOTO);
|
||||
if(n->pc) {
|
||||
patch(p, n->pc);
|
||||
return;
|
||||
}
|
||||
if(n->label)
|
||||
patch(n->label, pc-1);
|
||||
n->label = p;
|
||||
return;
|
||||
|
||||
case OCASE:
|
||||
l = n->left;
|
||||
if(cases == C)
|
||||
diag(n, "case/default outside a switch");
|
||||
if(l == Z) {
|
||||
cas();
|
||||
cases->val = 0;
|
||||
cases->def = 1;
|
||||
cases->label = pc;
|
||||
goto rloop;
|
||||
}
|
||||
complex(l);
|
||||
if(l->type == T)
|
||||
goto rloop;
|
||||
if(l->op == OCONST)
|
||||
if(typechl[l->type->etype]) {
|
||||
cas();
|
||||
cases->val = l->vconst;
|
||||
cases->def = 0;
|
||||
cases->label = pc;
|
||||
goto rloop;
|
||||
}
|
||||
diag(n, "case expression must be integer constant");
|
||||
goto rloop;
|
||||
|
||||
case OSWITCH:
|
||||
l = n->left;
|
||||
complex(l);
|
||||
if(l->type == T)
|
||||
break;
|
||||
if(!typechl[l->type->etype]) {
|
||||
diag(n, "switch expression must be integer");
|
||||
break;
|
||||
}
|
||||
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
cn = cases;
|
||||
cases = C;
|
||||
cas();
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
gen(n->right);
|
||||
gbranch(OGOTO);
|
||||
patch(p, breakpc);
|
||||
|
||||
patch(sp, pc);
|
||||
regalloc(&nod, l, Z);
|
||||
nod.type = types[TLONG];
|
||||
cgen(l, &nod, 0);
|
||||
doswit(&nod);
|
||||
regfree(&nod);
|
||||
patch(spb, pc);
|
||||
|
||||
cases = cn;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OWHILE:
|
||||
case ODWHILE:
|
||||
l = n->left;
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
scc = continpc;
|
||||
continpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spc = p;
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
patch(spc, pc);
|
||||
if(n->op == OWHILE)
|
||||
patch(sp, pc);
|
||||
bcomplex(l, Z); /* test */
|
||||
patch(p, breakpc);
|
||||
|
||||
if(n->op == ODWHILE)
|
||||
patch(sp, pc);
|
||||
gen(n->right); /* body */
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
|
||||
patch(spb, pc);
|
||||
continpc = scc;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OFOR:
|
||||
l = n->left;
|
||||
gen(l->right->left); /* init */
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
scc = continpc;
|
||||
continpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spc = p;
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
patch(spc, pc);
|
||||
gen(l->right->right); /* inc */
|
||||
patch(sp, pc);
|
||||
if(l->left != Z) { /* test */
|
||||
bcomplex(l->left, Z);
|
||||
patch(p, breakpc);
|
||||
}
|
||||
gen(n->right); /* body */
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
|
||||
patch(spb, pc);
|
||||
continpc = scc;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OCONTINUE:
|
||||
if(continpc < 0) {
|
||||
diag(n, "continue not in a loop");
|
||||
break;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
break;
|
||||
|
||||
case OBREAK:
|
||||
if(breakpc < 0) {
|
||||
diag(n, "break not in a loop");
|
||||
break;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, breakpc);
|
||||
break;
|
||||
|
||||
case OIF:
|
||||
l = n->left;
|
||||
if(bcomplex(l, n->right)) {
|
||||
if(typefd[l->type->etype])
|
||||
f = !l->fconst;
|
||||
else
|
||||
f = !l->vconst;
|
||||
if(debug['c'])
|
||||
print("%L const if %s\n", nearln, f ? "false" : "true");
|
||||
if(f) {
|
||||
supgen(n->right->left);
|
||||
gen(n->right->right);
|
||||
}
|
||||
else {
|
||||
gen(n->right->left);
|
||||
supgen(n->right->right);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sp = p;
|
||||
if(n->right->left != Z)
|
||||
gen(n->right->left);
|
||||
if(n->right->right != Z) {
|
||||
gbranch(OGOTO);
|
||||
patch(sp, pc);
|
||||
sp = p;
|
||||
gen(n->right->right);
|
||||
}
|
||||
patch(sp, pc);
|
||||
}
|
||||
break;
|
||||
|
||||
case OSET:
|
||||
case OUSED:
|
||||
usedset(n->left, o);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usedset(Node *n, int o)
|
||||
{
|
||||
if(n->op == OLIST) {
|
||||
usedset(n->left, o);
|
||||
usedset(n->right, o);
|
||||
return;
|
||||
}
|
||||
complex(n);
|
||||
switch(n->op) {
|
||||
case OADDR: /* volatile */
|
||||
gins(ANOP, n, Z);
|
||||
break;
|
||||
case ONAME:
|
||||
if(o == OSET)
|
||||
gins(ANOP, Z, n);
|
||||
else
|
||||
gins(ANOP, n, Z);
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
@ -651,21 +257,3 @@ xcom(Node *n)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bcomplex(Node *n, Node *c)
|
||||
{
|
||||
|
||||
complex(n);
|
||||
if(n->type != T)
|
||||
if(tcompat(n, T, n->type, tnot))
|
||||
n->type = T;
|
||||
if(n->type != T) {
|
||||
if(c != Z && n->op == OCONST && deadheads(c))
|
||||
return 1;
|
||||
bool64(n);
|
||||
boolgen(n, 1, Z);
|
||||
} else
|
||||
gbranch(OGOTO);
|
||||
return 0;
|
||||
}
|
||||
|
142
src/cmd/5c/swt.c
142
src/cmd/5c/swt.c
@ -28,65 +28,11 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
int
|
||||
swcmp(const void *a1, const void *a2)
|
||||
{
|
||||
C1 *p1, *p2;
|
||||
|
||||
p1 = (C1*)a1;
|
||||
p2 = (C1*)a2;
|
||||
if(p1->val < p2->val)
|
||||
return -1;
|
||||
return p1->val > p2->val;
|
||||
}
|
||||
|
||||
void
|
||||
doswit(Node *n)
|
||||
{
|
||||
Case *c;
|
||||
C1 *q, *iq;
|
||||
int32 def, nc, i;
|
||||
Node tn;
|
||||
|
||||
def = 0;
|
||||
nc = 0;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def) {
|
||||
if(def)
|
||||
diag(n, "more than one default in switch");
|
||||
def = c->label;
|
||||
continue;
|
||||
}
|
||||
nc++;
|
||||
}
|
||||
|
||||
iq = alloc(nc*sizeof(C1));
|
||||
q = iq;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def)
|
||||
continue;
|
||||
q->label = c->label;
|
||||
q->val = c->val;
|
||||
q++;
|
||||
}
|
||||
qsort(iq, nc, sizeof(C1), swcmp);
|
||||
if(debug['W'])
|
||||
for(i=0; i<nc; i++)
|
||||
print("case %2ld: = %.8lux\n", i, iq[i].val);
|
||||
if(def == 0)
|
||||
def = breakpc;
|
||||
for(i=0; i<nc-1; i++)
|
||||
if(iq[i].val == iq[i+1].val)
|
||||
diag(n, "duplicate cases in switch %ld", iq[i].val);
|
||||
regalloc(&tn, ®node, Z);
|
||||
swit1(iq, nc, def, n, &tn);
|
||||
regfree(&tn);
|
||||
}
|
||||
|
||||
void
|
||||
swit1(C1 *q, int nc, int32 def, Node *n, Node *tn)
|
||||
swit1(C1 *q, int nc, int32 def, Node *n)
|
||||
{
|
||||
C1 *r;
|
||||
int i;
|
||||
@ -119,12 +65,12 @@ swit1(C1 *q, int nc, int32 def, Node *n, Node *tn)
|
||||
sp = p;
|
||||
gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
|
||||
patch(p, r->label);
|
||||
swit1(q, i, def, n, tn);
|
||||
swit1(q, i, def, n);
|
||||
|
||||
if(debug['W'])
|
||||
print("case < %.8lux\n", r->val);
|
||||
patch(sp, pc);
|
||||
swit1(r+1, nc-i-1, def, n, tn);
|
||||
swit1(r+1, nc-i-1, def, n);
|
||||
return;
|
||||
|
||||
direct:
|
||||
@ -152,16 +98,6 @@ direct:
|
||||
patch(p, def);
|
||||
}
|
||||
|
||||
void
|
||||
cas(void)
|
||||
{
|
||||
Case *c;
|
||||
|
||||
c = alloc(sizeof(*c));
|
||||
c->link = cases;
|
||||
cases = c;
|
||||
}
|
||||
|
||||
void
|
||||
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||
{
|
||||
@ -183,7 +119,7 @@ bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||
gopcode(OAS, n3, Z, n1);
|
||||
} else {
|
||||
regalloc(n1, l, nn);
|
||||
cgen(l, n1, 0);
|
||||
cgen(l, n1);
|
||||
}
|
||||
if(b->type->shift == 0 && typeu[b->type->etype]) {
|
||||
v = ~0 + (1L << b->type->nbits);
|
||||
@ -259,33 +195,6 @@ outstring(char *s, int32 n)
|
||||
return r;
|
||||
}
|
||||
|
||||
int32
|
||||
outlstring(ushort *s, int32 n)
|
||||
{
|
||||
char buf[2];
|
||||
int c;
|
||||
int32 r;
|
||||
|
||||
if(suppress)
|
||||
return nstring;
|
||||
while(nstring & 1)
|
||||
outstring("", 1);
|
||||
r = nstring;
|
||||
while(n > 0) {
|
||||
c = *s++;
|
||||
if(align(0, types[TCHAR], Aarg1)) {
|
||||
buf[0] = c>>8;
|
||||
buf[1] = c;
|
||||
} else {
|
||||
buf[0] = c;
|
||||
buf[1] = c>>8;
|
||||
}
|
||||
outstring(buf, 2);
|
||||
n -= sizeof(ushort);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
mulcon(Node *n, Node *nn)
|
||||
{
|
||||
@ -327,7 +236,7 @@ mulcon(Node *n, Node *nn)
|
||||
if(p[1] == 'i')
|
||||
p += 2;
|
||||
regalloc(&nod1, n, nn);
|
||||
cgen(l, &nod1, 0);
|
||||
cgen(l, &nod1);
|
||||
vs = v;
|
||||
regalloc(&nod2, n, Z);
|
||||
|
||||
@ -380,16 +289,6 @@ loop:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
void
|
||||
nullwarn(Node *l, Node *r)
|
||||
{
|
||||
warn(Z, "result of operation not used");
|
||||
if(l != Z)
|
||||
cgen(l, Z, 0);
|
||||
if(r != Z)
|
||||
cgen(r, Z, 0);
|
||||
}
|
||||
|
||||
void
|
||||
sextern(Sym *s, Node *a, int32 o, int32 w)
|
||||
{
|
||||
@ -692,35 +591,6 @@ zaddr(char *bp, Adr *a, int s)
|
||||
return bp;
|
||||
}
|
||||
|
||||
void
|
||||
ieeedtod(Ieee *ieee, double native)
|
||||
{
|
||||
double fr, ho, f;
|
||||
int exp;
|
||||
|
||||
if(native < 0) {
|
||||
ieeedtod(ieee, -native);
|
||||
ieee->h |= 0x80000000L;
|
||||
return;
|
||||
}
|
||||
if(native == 0) {
|
||||
ieee->l = 0;
|
||||
ieee->h = 0;
|
||||
return;
|
||||
}
|
||||
fr = frexp(native, &exp);
|
||||
f = 2097152L; /* shouldnt use fp constants here */
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->h = ho;
|
||||
ieee->h &= 0xfffffL;
|
||||
ieee->h |= (exp+1022L) << 20;
|
||||
f = 65536L;
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->l = ho;
|
||||
ieee->l <<= 16;
|
||||
ieee->l |= (int32)(fr*f);
|
||||
}
|
||||
|
||||
int32
|
||||
align(int32 i, Type *t, int op)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
void
|
||||
@ -200,7 +201,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
|
||||
nod.left = *fnxp;
|
||||
nod.right = n;
|
||||
nod.type = n->type;
|
||||
cgen(&nod, Z, 0);
|
||||
cgen(&nod, Z);
|
||||
(*fnxp)++;
|
||||
}
|
||||
return;
|
||||
@ -217,18 +218,18 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
|
||||
if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
|
||||
regaalloc1(tn1, n);
|
||||
if(n->complex >= FNX) {
|
||||
cgen(*fnxp, tn1, 0);
|
||||
cgen(*fnxp, tn1);
|
||||
(*fnxp)++;
|
||||
} else
|
||||
cgen(n, tn1, 0);
|
||||
cgen(n, tn1);
|
||||
return;
|
||||
}
|
||||
regalloc(tn1, n, Z);
|
||||
if(n->complex >= FNX) {
|
||||
cgen(*fnxp, tn1, 0);
|
||||
cgen(*fnxp, tn1);
|
||||
(*fnxp)++;
|
||||
} else
|
||||
cgen(n, tn1, 0);
|
||||
cgen(n, tn1);
|
||||
regaalloc(tn2, n);
|
||||
gopcode(OAS, tn1, Z, tn2);
|
||||
regfree(tn1);
|
||||
|
@ -39,3 +39,7 @@ clean:
|
||||
|
||||
install: $(TARG)
|
||||
cp $(TARG) $(BIN)/$(TARG)
|
||||
|
||||
%.$O: ../cc/%.c
|
||||
$(CC) $(CFLAGS) -c -I. -o $@ ../cc/$*.c
|
||||
|
||||
|
@ -174,6 +174,7 @@ EXTERN Prog* firstp;
|
||||
EXTERN Prog* lastp;
|
||||
EXTERN int32 maxargsafe;
|
||||
EXTERN int mnstring;
|
||||
EXTERN int retok;
|
||||
EXTERN Node* nodrat;
|
||||
EXTERN Node* nodret;
|
||||
EXTERN Node* nodsafe;
|
||||
@ -241,6 +242,8 @@ void usedset(Node*, int);
|
||||
void xcom(Node*);
|
||||
void indx(Node*);
|
||||
int bcomplex(Node*, Node*);
|
||||
Prog* gtext(Sym*, int32);
|
||||
vlong argsize(void);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
@ -256,14 +259,6 @@ int needreg(Node*, int);
|
||||
int hardconst(Node*);
|
||||
int immconst(Node*);
|
||||
|
||||
/*
|
||||
* cgen64.c
|
||||
*/
|
||||
int vaddr(Node*, int);
|
||||
void loadpair(Node*, Node*);
|
||||
int cgen64(Node*, Node*);
|
||||
void testv(Node*, int);
|
||||
|
||||
/*
|
||||
* txt.c
|
||||
*/
|
||||
|
@ -44,9 +44,8 @@ machcap(Node *n)
|
||||
case OASLMUL:
|
||||
if(typechl[n->type->etype])
|
||||
return 1;
|
||||
if(typev[n->type->etype]) {
|
||||
if(typev[n->type->etype])
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case OCOM:
|
||||
|
@ -1,168 +0,0 @@
|
||||
// Inferno utils/6c/swt.c
|
||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
|
||||
//
|
||||
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
int
|
||||
swcmp(const void *a1, const void *a2)
|
||||
{
|
||||
C1 *p1, *p2;
|
||||
|
||||
p1 = (C1*)a1;
|
||||
p2 = (C1*)a2;
|
||||
if(p1->val < p2->val)
|
||||
return -1;
|
||||
return p1->val > p2->val;
|
||||
}
|
||||
|
||||
void
|
||||
doswit(Node *n)
|
||||
{
|
||||
Case *c;
|
||||
C1 *q, *iq;
|
||||
int32 def, nc, i, isv;
|
||||
|
||||
def = 0;
|
||||
nc = 0;
|
||||
isv = 0;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def) {
|
||||
if(def)
|
||||
diag(n, "more than one default in switch");
|
||||
def = c->label;
|
||||
continue;
|
||||
}
|
||||
isv |= c->isv;
|
||||
nc++;
|
||||
}
|
||||
if(isv && !typev[n->type->etype])
|
||||
warn(n, "32-bit switch expression with 64-bit case constant");
|
||||
|
||||
iq = alloc(nc*sizeof(C1));
|
||||
q = iq;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def)
|
||||
continue;
|
||||
q->label = c->label;
|
||||
if(isv)
|
||||
q->val = c->val;
|
||||
else
|
||||
q->val = (int32)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */
|
||||
q++;
|
||||
}
|
||||
qsort(iq, nc, sizeof(C1), swcmp);
|
||||
if(debug['W'])
|
||||
for(i=0; i<nc; i++)
|
||||
print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val);
|
||||
for(i=0; i<nc-1; i++)
|
||||
if(iq[i].val == iq[i+1].val)
|
||||
diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
|
||||
if(def == 0) {
|
||||
def = breakpc;
|
||||
nbreak++;
|
||||
}
|
||||
swit1(iq, nc, def, n);
|
||||
}
|
||||
|
||||
void
|
||||
cas(void)
|
||||
{
|
||||
Case *c;
|
||||
|
||||
c = alloc(sizeof(*c));
|
||||
c->link = cases;
|
||||
cases = c;
|
||||
}
|
||||
|
||||
int32
|
||||
outlstring(ushort *s, int32 n)
|
||||
{
|
||||
char buf[2];
|
||||
int c;
|
||||
int32 r;
|
||||
|
||||
if(suppress)
|
||||
return nstring;
|
||||
while(nstring & 1)
|
||||
outstring("", 1);
|
||||
r = nstring;
|
||||
while(n > 0) {
|
||||
c = *s++;
|
||||
if(align(0, types[TCHAR], Aarg1)) {
|
||||
buf[0] = c>>8;
|
||||
buf[1] = c;
|
||||
} else {
|
||||
buf[0] = c;
|
||||
buf[1] = c>>8;
|
||||
}
|
||||
outstring(buf, 2);
|
||||
n -= sizeof(ushort);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
nullwarn(Node *l, Node *r)
|
||||
{
|
||||
warn(Z, "result of operation not used");
|
||||
if(l != Z)
|
||||
cgen(l, Z);
|
||||
if(r != Z)
|
||||
cgen(r, Z);
|
||||
}
|
||||
|
||||
void
|
||||
ieeedtod(Ieee *ieee, double native)
|
||||
{
|
||||
double fr, ho, f;
|
||||
int exp;
|
||||
|
||||
if(native < 0) {
|
||||
ieeedtod(ieee, -native);
|
||||
ieee->h |= 0x80000000L;
|
||||
return;
|
||||
}
|
||||
if(native == 0) {
|
||||
ieee->l = 0;
|
||||
ieee->h = 0;
|
||||
return;
|
||||
}
|
||||
fr = frexp(native, &exp);
|
||||
f = 2097152L; /* shouldnt use fp constants here */
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->h = ho;
|
||||
ieee->h &= 0xfffffL;
|
||||
ieee->h |= (exp+1022L) << 20;
|
||||
f = 65536L;
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->l = ho;
|
||||
ieee->l <<= 16;
|
||||
ieee->l |= (int32)(fr*f);
|
||||
}
|
@ -30,6 +30,18 @@
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
Prog*
|
||||
gtext(Sym *s, int32 stkoff)
|
||||
{
|
||||
vlong v;
|
||||
|
||||
v = argsize() << 32;
|
||||
v |= stkoff & 0xffffffff;
|
||||
|
||||
gpseudo(ATEXT, s, nodgconst(v, types[TVLONG]));
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
noretval(int n)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@ OFILES=\
|
||||
list.$O\
|
||||
machcap.$O\
|
||||
mul.$O\
|
||||
pgen.$O\
|
||||
pswt.$O\
|
||||
peep.$O\
|
||||
reg.$O\
|
||||
sgen.$O\
|
||||
@ -39,3 +41,7 @@ clean:
|
||||
|
||||
install: $(TARG)
|
||||
cp $(TARG) $(BIN)/$(TARG)
|
||||
|
||||
%.$O: ../cc/%.c
|
||||
$(CC) $(CFLAGS) -c -I. -o $@ ../cc/$*.c
|
||||
|
||||
|
@ -95,6 +95,7 @@ struct Case
|
||||
int32 val;
|
||||
int32 label;
|
||||
char def;
|
||||
char isv;
|
||||
};
|
||||
#define C ((Case*)0)
|
||||
|
||||
@ -162,6 +163,7 @@ struct Rgn
|
||||
};
|
||||
|
||||
EXTERN int32 breakpc;
|
||||
EXTERN int32 nbreak;
|
||||
EXTERN Case* cases;
|
||||
EXTERN Node constnode;
|
||||
EXTERN Node fconstnode;
|
||||
@ -240,6 +242,8 @@ void usedset(Node*, int);
|
||||
void xcom(Node*);
|
||||
void indx(Node*);
|
||||
int bcomplex(Node*, Node*);
|
||||
Prog* gtext(Sym*, int32);
|
||||
vlong argsize(void);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
|
@ -30,411 +30,13 @@
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
int32
|
||||
argsize(void)
|
||||
Prog*
|
||||
gtext(Sym *s, int32 stkoff)
|
||||
{
|
||||
Type *t;
|
||||
int32 s;
|
||||
|
||||
//print("t=%T\n", thisfn);
|
||||
s = 0;
|
||||
for(t=thisfn->down; t!=T; t=t->down) {
|
||||
switch(t->etype) {
|
||||
case TVOID:
|
||||
break;
|
||||
case TDOT:
|
||||
s += 64;
|
||||
break;
|
||||
default:
|
||||
s = align(s, t, Aarg1);
|
||||
s = align(s, t, Aarg2);
|
||||
break;
|
||||
}
|
||||
//print(" %d %T\n", s, t);
|
||||
}
|
||||
return (s+7) & ~7;
|
||||
}
|
||||
|
||||
void
|
||||
codgen(Node *n, Node *nn)
|
||||
{
|
||||
Prog *sp;
|
||||
Node *n1, nod, nod1;
|
||||
|
||||
cursafe = 0;
|
||||
curarg = 0;
|
||||
maxargsafe = 0;
|
||||
|
||||
/*
|
||||
* isolate name
|
||||
*/
|
||||
for(n1 = nn;; n1 = n1->left) {
|
||||
if(n1 == Z) {
|
||||
diag(nn, "cant find function name");
|
||||
return;
|
||||
}
|
||||
if(n1->op == ONAME)
|
||||
break;
|
||||
}
|
||||
nearln = nn->lineno;
|
||||
|
||||
gpseudo(ATEXT, n1->sym, nodconst(stkoff));
|
||||
gpseudo(ATEXT, s, nodconst(stkoff));
|
||||
p->to.type = D_CONST2;
|
||||
p->to.offset2 = argsize();
|
||||
|
||||
/*
|
||||
* isolate first argument
|
||||
*/
|
||||
if(REGARG) {
|
||||
if(typesuv[thisfn->link->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nodreg(&nod, &nod1, REGARG);
|
||||
gmove(&nod, &nod1);
|
||||
} else
|
||||
if(firstarg && typechlp[firstargtype->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nod1.sym = firstarg;
|
||||
nod1.type = firstargtype;
|
||||
nod1.xoffset = align(0, firstargtype, Aarg1);
|
||||
nod1.etype = firstargtype->etype;
|
||||
nodreg(&nod, &nod1, REGARG);
|
||||
gmove(&nod, &nod1);
|
||||
}
|
||||
}
|
||||
|
||||
sp = p;
|
||||
retok = 0;
|
||||
gen(n);
|
||||
if(!retok)
|
||||
if(thisfn->link->etype != TVOID)
|
||||
warn(Z, "no return at end of function: %s", n1->sym->name);
|
||||
noretval(3);
|
||||
if(thisfn && thisfn->link && typefd[thisfn->link->etype])
|
||||
gins(AFLDZ, Z, Z);
|
||||
gbranch(ORETURN);
|
||||
|
||||
if(!debug['N'] || debug['R'] || debug['P'])
|
||||
regopt(sp);
|
||||
sp->to.offset += maxargsafe;
|
||||
}
|
||||
|
||||
void
|
||||
supgen(Node *n)
|
||||
{
|
||||
int32 spc;
|
||||
Prog *sp;
|
||||
|
||||
if(n == Z)
|
||||
return;
|
||||
suppress++;
|
||||
spc = pc;
|
||||
sp = lastp;
|
||||
gen(n);
|
||||
lastp = sp;
|
||||
pc = spc;
|
||||
sp->link = nil;
|
||||
suppress--;
|
||||
}
|
||||
|
||||
void
|
||||
gen(Node *n)
|
||||
{
|
||||
Node *l, nod;
|
||||
Prog *sp, *spc, *spb;
|
||||
Case *cn;
|
||||
int32 sbc, scc;
|
||||
int f, o;
|
||||
|
||||
loop:
|
||||
if(n == Z)
|
||||
return;
|
||||
nearln = n->lineno;
|
||||
o = n->op;
|
||||
if(debug['G'])
|
||||
if(o != OLIST)
|
||||
print("%L %O\n", nearln, o);
|
||||
|
||||
retok = 0;
|
||||
switch(o) {
|
||||
|
||||
default:
|
||||
complex(n);
|
||||
cgen(n, Z);
|
||||
break;
|
||||
|
||||
case OLIST:
|
||||
gen(n->left);
|
||||
|
||||
rloop:
|
||||
n = n->right;
|
||||
goto loop;
|
||||
|
||||
case ORETURN:
|
||||
retok = 1;
|
||||
complex(n);
|
||||
if(n->type == T)
|
||||
break;
|
||||
l = n->left;
|
||||
if(l == Z) {
|
||||
noretval(3);
|
||||
if(typefd[n->type->etype])
|
||||
gins(AFLDZ, Z, Z);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
}
|
||||
if(typesuv[n->type->etype]) {
|
||||
sugen(l, nodret, n->type->width);
|
||||
noretval(3);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
}
|
||||
regret(&nod, n);
|
||||
cgen(l, &nod);
|
||||
regfree(&nod);
|
||||
if(typefd[n->type->etype])
|
||||
noretval(1);
|
||||
else
|
||||
noretval(2);
|
||||
gbranch(ORETURN);
|
||||
break;
|
||||
|
||||
case OLABEL:
|
||||
l = n->left;
|
||||
if(l) {
|
||||
l->xoffset = pc;
|
||||
if(l->label)
|
||||
patch(l->label, pc);
|
||||
}
|
||||
gbranch(OGOTO); /* prevent self reference in reg */
|
||||
patch(p, pc);
|
||||
goto rloop;
|
||||
|
||||
case OGOTO:
|
||||
retok = 1;
|
||||
n = n->left;
|
||||
if(n == Z)
|
||||
return;
|
||||
if(n->complex == 0) {
|
||||
diag(Z, "label undefined: %s", n->sym->name);
|
||||
return;
|
||||
}
|
||||
if(suppress)
|
||||
return;
|
||||
gbranch(OGOTO);
|
||||
if(n->xoffset) {
|
||||
patch(p, n->xoffset);
|
||||
return;
|
||||
}
|
||||
if(n->label)
|
||||
patch(n->label, pc-1);
|
||||
n->label = p;
|
||||
return;
|
||||
|
||||
case OCASE:
|
||||
l = n->left;
|
||||
if(cases == C)
|
||||
diag(n, "case/default outside a switch");
|
||||
if(l == Z) {
|
||||
cas();
|
||||
cases->val = 0;
|
||||
cases->def = 1;
|
||||
cases->label = pc;
|
||||
goto rloop;
|
||||
}
|
||||
complex(l);
|
||||
if(l->type == T)
|
||||
goto rloop;
|
||||
if(l->op == OCONST)
|
||||
if(typechl[l->type->etype]) {
|
||||
cas();
|
||||
cases->val = l->vconst;
|
||||
cases->def = 0;
|
||||
cases->label = pc;
|
||||
goto rloop;
|
||||
}
|
||||
diag(n, "case expression must be integer constant");
|
||||
goto rloop;
|
||||
|
||||
case OSWITCH:
|
||||
l = n->left;
|
||||
complex(l);
|
||||
if(l->type == T)
|
||||
break;
|
||||
if(!typechl[l->type->etype]) {
|
||||
diag(n, "switch expression must be integer");
|
||||
break;
|
||||
}
|
||||
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
cn = cases;
|
||||
cases = C;
|
||||
cas();
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
gen(n->right);
|
||||
gbranch(OGOTO);
|
||||
patch(p, breakpc);
|
||||
|
||||
patch(sp, pc);
|
||||
regalloc(&nod, l, Z);
|
||||
nod.type = types[TLONG];
|
||||
cgen(l, &nod);
|
||||
doswit(&nod);
|
||||
regfree(&nod);
|
||||
patch(spb, pc);
|
||||
|
||||
cases = cn;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OWHILE:
|
||||
case ODWHILE:
|
||||
l = n->left;
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
scc = continpc;
|
||||
continpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spc = p;
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
patch(spc, pc);
|
||||
if(n->op == OWHILE)
|
||||
patch(sp, pc);
|
||||
bcomplex(l, Z); /* test */
|
||||
patch(p, breakpc);
|
||||
|
||||
if(n->op == ODWHILE)
|
||||
patch(sp, pc);
|
||||
gen(n->right); /* body */
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
|
||||
patch(spb, pc);
|
||||
continpc = scc;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OFOR:
|
||||
l = n->left;
|
||||
gen(l->right->left); /* init */
|
||||
gbranch(OGOTO); /* entry */
|
||||
sp = p;
|
||||
|
||||
scc = continpc;
|
||||
continpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spc = p;
|
||||
|
||||
sbc = breakpc;
|
||||
breakpc = pc;
|
||||
gbranch(OGOTO);
|
||||
spb = p;
|
||||
|
||||
patch(spc, pc);
|
||||
gen(l->right->right); /* inc */
|
||||
patch(sp, pc);
|
||||
if(l->left != Z) { /* test */
|
||||
bcomplex(l->left, Z);
|
||||
patch(p, breakpc);
|
||||
}
|
||||
gen(n->right); /* body */
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
|
||||
patch(spb, pc);
|
||||
continpc = scc;
|
||||
breakpc = sbc;
|
||||
break;
|
||||
|
||||
case OCONTINUE:
|
||||
if(continpc < 0) {
|
||||
diag(n, "continue not in a loop");
|
||||
break;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, continpc);
|
||||
break;
|
||||
|
||||
case OBREAK:
|
||||
if(breakpc < 0) {
|
||||
diag(n, "break not in a loop");
|
||||
break;
|
||||
}
|
||||
gbranch(OGOTO);
|
||||
patch(p, breakpc);
|
||||
break;
|
||||
|
||||
case OIF:
|
||||
l = n->left;
|
||||
if(bcomplex(l, n->right)) {
|
||||
if(typefd[l->type->etype])
|
||||
f = !l->fconst;
|
||||
else
|
||||
f = !l->vconst;
|
||||
if(debug['c'])
|
||||
print("%L const if %s\n", nearln, f ? "false" : "true");
|
||||
if(f) {
|
||||
supgen(n->right->left);
|
||||
gen(n->right->right);
|
||||
}
|
||||
else {
|
||||
gen(n->right->left);
|
||||
supgen(n->right->right);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sp = p;
|
||||
if(n->right->left != Z)
|
||||
gen(n->right->left);
|
||||
if(n->right->right != Z) {
|
||||
gbranch(OGOTO);
|
||||
patch(sp, pc);
|
||||
sp = p;
|
||||
gen(n->right->right);
|
||||
}
|
||||
patch(sp, pc);
|
||||
}
|
||||
break;
|
||||
|
||||
case OSET:
|
||||
case OUSED:
|
||||
usedset(n->left, o);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usedset(Node *n, int o)
|
||||
{
|
||||
if(n->op == OLIST) {
|
||||
usedset(n->left, o);
|
||||
usedset(n->right, o);
|
||||
return;
|
||||
}
|
||||
complex(n);
|
||||
switch(n->op) {
|
||||
case OADDR: /* volatile */
|
||||
gins(ANOP, n, Z);
|
||||
break;
|
||||
case ONAME:
|
||||
if(o == OSET)
|
||||
gins(ANOP, Z, n);
|
||||
else
|
||||
gins(ANOP, n, Z);
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
@ -872,33 +474,3 @@ indx(Node *n)
|
||||
prtree(idx.basetree, "base");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
bcomplex(Node *n, Node *c)
|
||||
{
|
||||
Node *b, nod;
|
||||
|
||||
complex(n);
|
||||
if(n->type != T)
|
||||
if(tcompat(n, T, n->type, tnot))
|
||||
n->type = T;
|
||||
if(n->type != T) {
|
||||
if(c != Z && n->op == OCONST && deadheads(c))
|
||||
return 1;
|
||||
if(typev[n->type->etype] && machcap(Z)) {
|
||||
b = &nod;
|
||||
b->op = ONE;
|
||||
b->left = n;
|
||||
b->right = new(0, Z, Z);
|
||||
*b->right = *nodconst(0);
|
||||
b->right->type = n->type;
|
||||
b->type = types[TLONG];
|
||||
cgen64(b, Z);
|
||||
return 0;
|
||||
}
|
||||
bool64(n);
|
||||
boolgen(n, 1, Z);
|
||||
} else
|
||||
gbranch(OGOTO);
|
||||
return 0;
|
||||
}
|
||||
|
128
src/cmd/8c/swt.c
128
src/cmd/8c/swt.c
@ -30,58 +30,6 @@
|
||||
|
||||
#include "gc.h"
|
||||
|
||||
int
|
||||
swcmp(const void *a1, const void *a2)
|
||||
{
|
||||
C1 *p1, *p2;
|
||||
|
||||
p1 = (C1*)a1;
|
||||
p2 = (C1*)a2;
|
||||
if(p1->val < p2->val)
|
||||
return -1;
|
||||
return p1->val > p2->val;
|
||||
}
|
||||
|
||||
void
|
||||
doswit(Node *n)
|
||||
{
|
||||
Case *c;
|
||||
C1 *q, *iq;
|
||||
int32 def, nc, i;
|
||||
|
||||
def = 0;
|
||||
nc = 0;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def) {
|
||||
if(def)
|
||||
diag(n, "more than one default in switch");
|
||||
def = c->label;
|
||||
continue;
|
||||
}
|
||||
nc++;
|
||||
}
|
||||
|
||||
iq = alloc(nc*sizeof(C1));
|
||||
q = iq;
|
||||
for(c = cases; c->link != C; c = c->link) {
|
||||
if(c->def)
|
||||
continue;
|
||||
q->label = c->label;
|
||||
q->val = c->val;
|
||||
q++;
|
||||
}
|
||||
qsort(iq, nc, sizeof(C1), swcmp);
|
||||
if(debug['W'])
|
||||
for(i=0; i<nc; i++)
|
||||
print("case %2ld: = %.8lux\n", i, iq[i].val);
|
||||
if(def == 0)
|
||||
def = breakpc;
|
||||
for(i=0; i<nc-1; i++)
|
||||
if(iq[i].val == iq[i+1].val)
|
||||
diag(n, "duplicate cases in switch %ld", iq[i].val);
|
||||
swit1(iq, nc, def, n);
|
||||
}
|
||||
|
||||
void
|
||||
swit1(C1 *q, int nc, int32 def, Node *n)
|
||||
{
|
||||
@ -118,16 +66,6 @@ swit1(C1 *q, int nc, int32 def, Node *n)
|
||||
swit1(r+1, nc-i-1, def, n);
|
||||
}
|
||||
|
||||
void
|
||||
cas(void)
|
||||
{
|
||||
Case *c;
|
||||
|
||||
c = alloc(sizeof(*c));
|
||||
c->link = cases;
|
||||
cases = c;
|
||||
}
|
||||
|
||||
void
|
||||
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
|
||||
{
|
||||
@ -219,43 +157,6 @@ outstring(char *s, int32 n)
|
||||
return r;
|
||||
}
|
||||
|
||||
int32
|
||||
outlstring(ushort *s, int32 n)
|
||||
{
|
||||
char buf[2];
|
||||
int c;
|
||||
int32 r;
|
||||
|
||||
if(suppress)
|
||||
return nstring;
|
||||
while(nstring & 1)
|
||||
outstring("", 1);
|
||||
r = nstring;
|
||||
while(n > 0) {
|
||||
c = *s++;
|
||||
if(align(0, types[TCHAR], Aarg1)) {
|
||||
buf[0] = c>>8;
|
||||
buf[1] = c;
|
||||
} else {
|
||||
buf[0] = c;
|
||||
buf[1] = c>>8;
|
||||
}
|
||||
outstring(buf, 2);
|
||||
n -= sizeof(ushort);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
nullwarn(Node *l, Node *r)
|
||||
{
|
||||
warn(Z, "result of operation not used");
|
||||
if(l != Z)
|
||||
cgen(l, Z);
|
||||
if(r != Z)
|
||||
cgen(r, Z);
|
||||
}
|
||||
|
||||
void
|
||||
sextern(Sym *s, Node *a, int32 o, int32 w)
|
||||
{
|
||||
@ -585,35 +486,6 @@ zaddr(Biobuf *b, Adr *a, int s)
|
||||
Bputc(b, a->type);
|
||||
}
|
||||
|
||||
void
|
||||
ieeedtod(Ieee *ieee, double native)
|
||||
{
|
||||
double fr, ho, f;
|
||||
int exp;
|
||||
|
||||
if(native < 0) {
|
||||
ieeedtod(ieee, -native);
|
||||
ieee->h |= 0x80000000L;
|
||||
return;
|
||||
}
|
||||
if(native == 0) {
|
||||
ieee->l = 0;
|
||||
ieee->h = 0;
|
||||
return;
|
||||
}
|
||||
fr = frexp(native, &exp);
|
||||
f = 2097152L; /* shouldnt use fp constants here */
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->h = ho;
|
||||
ieee->h &= 0xfffffL;
|
||||
ieee->h |= (exp+1022L) << 20;
|
||||
f = 65536L;
|
||||
fr = modf(fr*f, &ho);
|
||||
ieee->l = ho;
|
||||
ieee->l <<= 16;
|
||||
ieee->l |= (int32)(fr*f);
|
||||
}
|
||||
|
||||
int32
|
||||
align(int32 i, Type *t, int op)
|
||||
{
|
||||
|
@ -60,7 +60,6 @@ codgen(Node *n, Node *nn)
|
||||
{
|
||||
Prog *sp;
|
||||
Node *n1, nod, nod1;
|
||||
vlong v;
|
||||
|
||||
cursafe = 0;
|
||||
curarg = 0;
|
||||
@ -79,22 +78,18 @@ codgen(Node *n, Node *nn)
|
||||
}
|
||||
nearln = nn->lineno;
|
||||
|
||||
v = argsize() << 32;
|
||||
v |= stkoff & 0xffffffff;
|
||||
|
||||
gpseudo(ATEXT, n1->sym, nodgconst(v, types[TVLONG]));
|
||||
sp = p;
|
||||
p = gtext(n1->sym, stkoff);
|
||||
|
||||
/*
|
||||
* isolate first argument
|
||||
*/
|
||||
if(REGARG) {
|
||||
if(typecmplx[thisfn->link->etype]) {
|
||||
if(typesuv[thisfn->link->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nodreg(&nod, &nod1, REGARG);
|
||||
gmove(&nod, &nod1);
|
||||
} else
|
||||
if(firstarg && typeword[firstargtype->etype]) {
|
||||
if(firstarg && typechlp[firstargtype->etype]) {
|
||||
nod1 = *nodret->left;
|
||||
nod1.sym = firstarg;
|
||||
nod1.type = firstargtype;
|
||||
@ -105,6 +100,9 @@ codgen(Node *n, Node *nn)
|
||||
}
|
||||
}
|
||||
|
||||
sp = p;
|
||||
retok = 0;
|
||||
|
||||
canreach = 1;
|
||||
warnreach = 1;
|
||||
gen(n);
|
||||
@ -125,7 +123,7 @@ void
|
||||
supgen(Node *n)
|
||||
{
|
||||
int owarn;
|
||||
int32 spc;
|
||||
long spc;
|
||||
Prog *sp;
|
||||
|
||||
if(n == Z)
|
||||
@ -149,7 +147,7 @@ gen(Node *n)
|
||||
Node *l, nod;
|
||||
Prog *sp, *spc, *spb;
|
||||
Case *cn;
|
||||
int32 sbc, scc;
|
||||
long sbc, scc;
|
||||
int snbreak, sncontin;
|
||||
int f, o, oldreach;
|
||||
|
||||
@ -563,6 +561,7 @@ usedset(Node *n, int o)
|
||||
int
|
||||
bcomplex(Node *n, Node *c)
|
||||
{
|
||||
Node *b, nod;
|
||||
|
||||
complex(n);
|
||||
if(n->type != T)
|
||||
@ -574,7 +573,19 @@ bcomplex(Node *n, Node *c)
|
||||
}
|
||||
if(c != Z && n->op == OCONST && deadheads(c))
|
||||
return 1;
|
||||
if(typev[n->type->etype] && machcap(Z)) {
|
||||
b = &nod;
|
||||
b->op = ONE;
|
||||
b->left = n;
|
||||
b->right = new(0, Z, Z);
|
||||
*b->right = *nodconst(0);
|
||||
b->right->type = n->type;
|
||||
b->type = types[TLONG];
|
||||
cgen(b, Z);
|
||||
return 0;
|
||||
}
|
||||
bool64(n);
|
||||
boolgen(n, 1, Z);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user