summaryrefslogtreecommitdiff
path: root/sys/src/cmd/cc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-07-30 19:11:16 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-07-30 19:11:16 +0200
commit4f33c88a51587681b7be1ae57cfbc43b627c6bc4 (patch)
tree25560404dc80007e5dc268811242c9071f6a1017 /sys/src/cmd/cc
parentfcc5e75d07e5bc6cb3ddac6d9a437e7ec62d0d95 (diff)
import updated compilers from sources
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r--sys/src/cmd/cc/acid.c2
-rw-r--r--sys/src/cmd/cc/cc.h13
-rw-r--r--sys/src/cmd/cc/cc.y18
-rw-r--r--sys/src/cmd/cc/com.c119
-rw-r--r--sys/src/cmd/cc/com64.c2
-rw-r--r--sys/src/cmd/cc/dcl.c12
-rw-r--r--sys/src/cmd/cc/lex.c4
-rw-r--r--sys/src/cmd/cc/macbody4
-rw-r--r--sys/src/cmd/cc/pgen.c69
-rw-r--r--sys/src/cmd/cc/pswt.c62
-rw-r--r--sys/src/cmd/cc/sub.c2
11 files changed, 264 insertions, 43 deletions
diff --git a/sys/src/cmd/cc/acid.c b/sys/src/cmd/cc/acid.c
index 8ad20a913..d42b47b42 100644
--- a/sys/src/cmd/cc/acid.c
+++ b/sys/src/cmd/cc/acid.c
@@ -90,6 +90,8 @@ acidinit(void)
if(types[TINT]->width != types[TSHORT]->width)
warn(Z, "acidmember int not long or short");
}
+ if(types[TIND]->width == types[TUVLONG]->width)
+ acidchar[TIND] = 'Y';
}
diff --git a/sys/src/cmd/cc/cc.h b/sys/src/cmd/cc/cc.h
index c46b972f9..d66faaa11 100644
--- a/sys/src/cmd/cc/cc.h
+++ b/sys/src/cmd/cc/cc.h
@@ -22,15 +22,15 @@ typedef struct Bits Bits;
#define NHUNK 50000L
#define BUFSIZ 8192
-#define NSYMB 500
+#define NSYMB 1500
#define NHASH 1024
#define STRINGSZ 200
#define HISTSZ 20
-#define YYMAXDEPTH 500
+#define YYMAXDEPTH 1500
#define NTERM 10
#define MAXALIGN 7
-#define SIGN(n) ((vlong)1<<(n-1))
+#define SIGN(n) (1ULL<<(n-1))
#define MASK(n) (SIGN(n)|(SIGN(n)-1))
#define BITS 5
@@ -294,6 +294,7 @@ enum
OINDEX,
OFAS,
OREGPAIR,
+ OEXREG,
OEND
};
@@ -477,6 +478,7 @@ EXTERN int packflg;
EXTERN int fproundflg;
EXTERN int profileflg;
EXTERN int ncontin;
+EXTERN int newvlongcode;
EXTERN int canreach;
EXTERN int warnreach;
EXTERN Bits zbits;
@@ -507,6 +509,7 @@ extern char typechlvp[];
extern char typechlp[];
extern char typechlpfd[];
+EXTERN char* typeswitch;
EXTERN char* typeword;
EXTERN char* typecmplx;
@@ -614,7 +617,7 @@ int rsametype(Type*, Type*, int, int);
int sametype(Type*, Type*);
ulong sign(Sym*);
ulong signature(Type*);
-void suallign(Type*);
+void sualign(Type*);
void tmerge(Type*, Sym*);
void walkparam(Node*, int);
void xdecl(int, Type*, Sym*);
@@ -632,6 +635,8 @@ int tcomo(Node*, int);
int tcomx(Node*);
int tlvalue(Node*);
void constas(Node*, Type*, Type*);
+Node* uncomma(Node*);
+Node* uncomargs(Node*);
/*
* con.c
diff --git a/sys/src/cmd/cc/cc.y b/sys/src/cmd/cc/cc.y
index 3057547b0..09b788598 100644
--- a/sys/src/cmd/cc/cc.y
+++ b/sys/src/cmd/cc/cc.y
@@ -8,12 +8,14 @@
struct
{
Type* t;
- char c;
+ uchar c;
} tycl;
struct
{
Type* t1;
Type* t2;
+ Type* t3;
+ uchar c;
} tyty;
struct
{
@@ -895,16 +897,22 @@ sbody:
{
$<tyty>$.t1 = strf;
$<tyty>$.t2 = strl;
+ $<tyty>$.t3 = lasttype;
+ $<tyty>$.c = lastclass;
strf = T;
strl = T;
lastbit = 0;
firstbit = 1;
+ lastclass = CXXX;
+ lasttype = T;
}
edecl '}'
{
$$ = strf;
strf = $<tyty>2.t1;
strl = $<tyty>2.t2;
+ lasttype = $<tyty>2.t3;
+ lastclass = $<tyty>2.c;
}
zctlist:
@@ -995,7 +1003,7 @@ complex:
if($$->link != T)
diag(Z, "redeclare tag: %s", $2->name);
$$->link = $4;
- suallign($$);
+ sualign($$);
}
| LSTRUCT sbody
{
@@ -1003,7 +1011,7 @@ complex:
sprint(symb, "_%d_", taggen);
$$ = dotag(lookup(), TSTRUCT, autobn);
$$->link = $2;
- suallign($$);
+ sualign($$);
}
| LUNION ltag
{
@@ -1020,7 +1028,7 @@ complex:
if($$->link != T)
diag(Z, "redeclare tag: %s", $2->name);
$$->link = $4;
- suallign($$);
+ sualign($$);
}
| LUNION sbody
{
@@ -1028,7 +1036,7 @@ complex:
sprint(symb, "_%d_", taggen);
$$ = dotag(lookup(), TUNION, autobn);
$$->link = $2;
- suallign($$);
+ sualign($$);
}
| LENUM ltag
{
diff --git a/sys/src/cmd/cc/com.c b/sys/src/cmd/cc/com.c
index 1401e48d4..8ff7c4663 100644
--- a/sys/src/cmd/cc/com.c
+++ b/sys/src/cmd/cc/com.c
@@ -1,6 +1,15 @@
#include "cc.h"
+typedef struct Com Com;
+struct Com
+{
+ int n;
+ Node *t[500];
+};
+
int compar(Node*, int);
+static void comma(Node*);
+static Node* commas(Com*, Node*);
void
complex(Node *n)
@@ -15,6 +24,8 @@ complex(Node *n)
prtree(n, "pre complex");
if(tcom(n))
return;
+ if(debug['y'] || 1)
+ comma(n);
if(debug['t'])
if(n->op != OCONST)
prtree(n, "t complex");
@@ -273,8 +284,11 @@ tcomo(Node *n, int f)
goto bad;
n->type = l->type;
if(n->type->etype == TIND)
- if(n->type->link->width < 1)
- diag(n, "inc/dec of a void pointer");
+ if(n->type->link->width < 1) {
+ snap(n->type->link);
+ if(n->type->link->width < 1)
+ diag(n, "inc/dec of a void pointer");
+ }
break;
case OEQ:
@@ -610,6 +624,8 @@ tcomo(Node *n, int f)
n->addable = 1;
if(n->class == CEXREG) {
n->op = OREGISTER;
+ if(thechar == '8')
+ n->op = OEXREG;
n->reg = n->sym->offset;
n->xoffset = 0;
break;
@@ -882,6 +898,101 @@ tlvalue(Node *n)
}
/*
+ * hoist comma operators out of expressions
+ * (a,b) OP c => (a, b OP c)
+ * OP(a,b) => (a, OP b)
+ * a OP (b,c) => (b, a OP c)
+ */
+
+static Node*
+comargs(Com *com, Node *n)
+{
+ if(n != Z && n->op == OLIST){
+ n->left = comargs(com, n->left);
+ n->right = comargs(com, n->right);
+ }
+ return commas(com, n);
+}
+
+static Node*
+commas(Com *com, Node *n)
+{
+ Node *t;
+
+ if(n == Z)
+ return n;
+ switch(n->op){
+ case OREGISTER:
+ case OINDREG:
+ case OCONST:
+ case ONAME:
+ case OSTRING:
+ /* leaf */
+ return n;
+
+ case OCOMMA:
+ t = commas(com, n->left);
+ if(com->n >= nelem(com->t))
+ fatal(n, "comma list overflow");
+ com->t[com->n++] = t;
+ return commas(com, n->right);
+
+ case OFUNC:
+ n->left = commas(com, n->left);
+ n->right = comargs(com, n->right);
+ return n;
+
+ case OCOND:
+ n->left = commas(com, n->left);
+ comma(n->right->left);
+ comma(n->right->right);
+ return n;
+
+ case OANDAND:
+ case OOROR:
+ n->left = commas(com, n->left);
+ comma(n->right);
+ return n;
+
+ case ORETURN:
+ comma(n->left);
+ return n;
+ }
+ n->left = commas(com, n->left);
+ if(n->right != Z)
+ n->right = commas(com, n->right);
+ return n;
+}
+
+static void
+comma(Node *n)
+{
+ Com com;
+ Node *nn;
+
+ com.n = 0;
+ nn = commas(&com, n);
+ if(com.n > 0){
+if(debug['y'])print("n=%d\n", com.n);
+if(debug['y']) prtree(nn, "res");
+ if(nn != n)
+ *n = *nn;
+ while(com.n > 0){
+if(debug['y']) prtree(com.t[com.n-1], "tree");
+ nn = new1(OXXX, Z, Z);
+ *nn = *n;
+ n->op = OCOMMA;
+ n->type = nn->type;
+ n->left = com.t[--com.n];
+ n->right = nn;
+ n->lineno = n->left->lineno;
+ }
+if(debug['y']) prtree(n, "final");
+ }else if(n != nn)
+ fatal(n, "odd tree");
+}
+
+/*
* general rewrite
* (IND(ADDR x)) ==> x
* (ADDR(IND x)) ==> x
@@ -934,7 +1045,8 @@ loop:
if(n->op == OCONST)
break;
}
- if(nocast(l->type, n->type)) {
+ if(nocast(l->type, n->type) &&
+ (!typefd[l->type->etype] || typeu[l->type->etype] && typeu[n->type->etype])) {
l->type = n->type;
*n = *l;
}
@@ -1342,6 +1454,7 @@ useless:
else
snprint(cmpbuf, sizeof cmpbuf, "%T %s %s",
lt, cmps[relindex(n->op)], xbuf);
+if(debug['y']) prtree(n, "strange");
warn(n, "useless or misleading comparison: %s", cmpbuf);
return 0;
}
diff --git a/sys/src/cmd/cc/com64.c b/sys/src/cmd/cc/com64.c
index 53c3c9fca..f44a44ffe 100644
--- a/sys/src/cmd/cc/com64.c
+++ b/sys/src/cmd/cc/com64.c
@@ -274,8 +274,8 @@ com64(Node *n)
case ORETURN:
case OAS:
case OIND:
- case OCOMMA:
case OLIST:
+ case OCOMMA:
return 1;
case OADD:
a = nodaddv;
diff --git a/sys/src/cmd/cc/dcl.c b/sys/src/cmd/cc/dcl.c
index c21375a94..968654165 100644
--- a/sys/src/cmd/cc/dcl.c
+++ b/sys/src/cmd/cc/dcl.c
@@ -519,7 +519,7 @@ newlist(Node *l, Node *r)
}
void
-suallign(Type *t)
+sualign(Type *t)
{
Type *l;
long o, w;
@@ -581,7 +581,7 @@ suallign(Type *t)
return;
default:
- diag(Z, "unknown type in suallign: %T", t);
+ diag(Z, "unknown type in sualign: %T", t);
break;
}
}
@@ -1180,12 +1180,6 @@ paramconv(Type *t, int f)
{
switch(t->etype) {
- case TUNION:
- case TSTRUCT:
- if(t->width <= 0)
- diag(Z, "incomplete structure: %s", t->tag->name);
- break;
-
case TARRAY:
t = typ(TIND, t->link);
t->width = types[TIND]->width;
@@ -1283,6 +1277,8 @@ pdecl(int c, Type *t, Sym *s)
diag(Z, "parameter cannot have class: %s", s->name);
c = CPARAM;
}
+ if(typesu[t->etype] && t->width <= 0)
+ diag(Z, "incomplete structure: %s", t->tag->name);
adecl(c, t, s);
}
diff --git a/sys/src/cmd/cc/lex.c b/sys/src/cmd/cc/lex.c
index 74054aa22..2652cb8f8 100644
--- a/sys/src/cmd/cc/lex.c
+++ b/sys/src/cmd/cc/lex.c
@@ -1262,9 +1262,7 @@ loop:
if(i->f < 0)
goto pop;
fi.c = read(i->f, i->b, BUFSIZ) - 1;
- if(fi.c < -1)
- sysfatal("read error: %r");
- if(fi.c == -1) {
+ if(fi.c < 0) {
close(i->f);
linehist(0, 0);
goto pop;
diff --git a/sys/src/cmd/cc/macbody b/sys/src/cmd/cc/macbody
index e26dc427a..7c86bac19 100644
--- a/sys/src/cmd/cc/macbody
+++ b/sys/src/cmd/cc/macbody
@@ -25,7 +25,7 @@ getsym(void)
char *cp;
c = getnsc();
- if(!isalpha(c) && c != '_') {
+ if(!isalpha(c) && c != '_' && c < Runeself) {
unget(c);
return S;
}
@@ -33,7 +33,7 @@ getsym(void)
if(cp <= symb+NSYMB-4)
*cp++ = c;
c = getc();
- if(isalnum(c) || c == '_')
+ if(isalnum(c) || c == '_' || c >= Runeself)
continue;
unget(c);
break;
diff --git a/sys/src/cmd/cc/pgen.c b/sys/src/cmd/cc/pgen.c
index 131ff012b..c9002ac33 100644
--- a/sys/src/cmd/cc/pgen.c
+++ b/sys/src/cmd/cc/pgen.c
@@ -70,8 +70,12 @@ codgen(Node *n, Node *nn)
canreach = 1;
warnreach = 1;
gen(n);
- if(canreach && thisfn->link->etype != TVOID)
- warn(Z, "no return at end of function: %s", n1->sym->name);
+ if(canreach && thisfn->link->etype != TVOID){
+ if(debug['B'])
+ warn(Z, "no return at end of function: %s", n1->sym->name);
+ else
+ diag(Z, "no return at end of function: %s", n1->sym->name);
+ }
noretval(3);
gbranch(ORETURN);
@@ -105,10 +109,20 @@ supgen(Node *n)
warnreach = owarn;
}
+Node*
+uncomma(Node *n)
+{
+ while(n != Z && n->op == OCOMMA) {
+ cgen(n->left, Z);
+ n = n->right;
+ }
+ return n;
+}
+
void
gen(Node *n)
{
- Node *l, nod;
+ Node *l, nod, rn;
Prog *sp, *spc, *spb;
Case *cn;
long sbc, scc;
@@ -129,6 +143,7 @@ loop:
case OLABEL:
case OCASE:
case OLIST:
+ case OCOMMA:
case OBREAK:
case OFOR:
case OWHILE:
@@ -151,6 +166,7 @@ loop:
break;
case OLIST:
+ case OCOMMA:
gen(n->left);
rloop:
@@ -163,7 +179,7 @@ loop:
complex(n);
if(n->type == T)
break;
- l = n->left;
+ l = uncomma(n->left);
if(l == Z) {
noretval(3);
gbranch(ORETURN);
@@ -181,6 +197,20 @@ loop:
gbranch(ORETURN);
break;
}
+ if(newvlongcode && !typefd[n->type->etype]){
+ regret(&rn, n);
+ regfree(&rn);
+ nod = znode;
+ nod.op = OAS;
+ nod.left = &rn;
+ nod.right = l;
+ nod.type = n->type;
+ nod.complex = l->complex;
+ cgen(&nod, Z);
+ noretval(2);
+ gbranch(ORETURN);
+ break;
+ }
regret(&nod, n);
cgen(l, &nod);
regfree(&nod);
@@ -241,16 +271,15 @@ loop:
complex(l);
if(l->type == T)
goto rloop;
- if(l->op == OCONST)
- if(typeword[l->type->etype] && l->type->etype != TIND) {
- casf();
- cases->val = l->vconst;
- cases->def = 0;
- cases->label = pc;
- cases->isv = typev[l->type->etype];
+ if(l->op != OCONST || !typeswitch[l->type->etype]) {
+ diag(n, "case expression must be integer constant");
goto rloop;
}
- diag(n, "case expression must be integer constant");
+ casf();
+ cases->val = l->vconst;
+ cases->def = 0;
+ cases->label = pc;
+ cases->isv = typev[l->type->etype];
goto rloop;
case OSWITCH:
@@ -258,7 +287,7 @@ loop:
complex(l);
if(l->type == T)
break;
- if(!typeword[l->type->etype] || l->type->etype == TIND) {
+ if(!typeswitch[l->type->etype]) {
diag(n, "switch expression must be integer");
break;
}
@@ -531,6 +560,8 @@ usedset(Node *n, int o)
int
bcomplex(Node *n, Node *c)
{
+ Node *b, nod;
+
complex(n);
if(n->type != T)
@@ -542,6 +573,18 @@ bcomplex(Node *n, Node *c)
}
if(c != Z && n->op == OCONST && deadheads(c))
return 1;
+ /* this is not quite right yet, so ignore it for now */
+ if(0 && newvlongcode && 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;
diff --git a/sys/src/cmd/cc/pswt.c b/sys/src/cmd/cc/pswt.c
index 6ef4f2fbe..df1cda4a4 100644
--- a/sys/src/cmd/cc/pswt.c
+++ b/sys/src/cmd/cc/pswt.c
@@ -16,8 +16,10 @@ void
doswit(Node *n)
{
Case *c;
- C1 *q, *iq;
- long def, nc, i, isv;
+ C1 *q, *iq, *iqh, *iql;
+ long def, nc, i, j, isv, nh;
+ Prog *hsb;
+ Node *vr[2];
int dup;
def = 0;
@@ -33,14 +35,20 @@ doswit(Node *n)
isv |= c->isv;
nc++;
}
- if(isv && !typev[n->type->etype])
+ if(typev[n->type->etype])
+ isv = 1;
+ else if(isv){
warn(n, "32-bit switch expression with 64-bit case constant");
+ isv = 0;
+ }
iq = alloc(nc*sizeof(C1));
q = iq;
for(c = cases; c->link != C; c = c->link) {
if(c->def)
continue;
+ if(c->isv && !isv)
+ continue; /* can never match */
q->label = c->label;
if(isv)
q->val = c->val;
@@ -64,7 +72,53 @@ doswit(Node *n)
def = breakpc;
nbreak++;
}
- swit1(iq, nc, def, n);
+ if(!isv || ewidth[TIND] > ewidth[TLONG] || n->op == OREGISTER) {
+ swit1(iq, nc, def, n);
+ return;
+ }
+
+ /*
+ * 64-bit case on 32-bit machine:
+ * switch on high-order words, and
+ * in each of those, switch on low-order words
+ */
+ if(n->op != OREGPAIR)
+ fatal(n, "internal: expected register pair");
+ if(thechar == '8'){ /* TO DO: need an enquiry function */
+ vr[0] = n->left; /* low */
+ vr[1] = n->right; /* high */
+ }else{
+ vr[0] = n->right;
+ vr[1] = n->left;
+ }
+ vr[0]->type = types[TLONG];
+ vr[1]->type = types[TLONG];
+ gbranch(OGOTO);
+ hsb = p;
+ iqh = alloc(nc*sizeof(C1));
+ iql = alloc(nc*sizeof(C1));
+ nh = 0;
+ for(i=0; i<nc;){
+ iqh[nh].val = iq[i].val >> 32;
+ q = iql;
+ /* iq is sorted, so equal top halves are adjacent */
+ for(j = i; j < nc; j++){
+ if((iq[j].val>>32) != iqh[nh].val)
+ break;
+ q->val = (long)iq[j].val;
+ q->label = iq[j].label;
+ q++;
+ }
+ qsort(iql, q-iql, sizeof(C1), swcmp);
+if(0){for(int k=0; k<(q-iql); k++)print("nh=%ld k=%d h=%#llux l=%#llux lab=%ld\n", nh, k, (vlong)iqh[nh].val, (vlong)iql[k].val, iql[k].label);}
+ iqh[nh].label = pc;
+ nh++;
+ swit1(iql, q-iql, def, vr[0]);
+ i = j;
+ }
+ patch(hsb, pc);
+if(0){for(int k=0; k<nh; k++)print("k*=%d h=%#llux lab=%ld\n", k, (vlong)iqh[k].val, iqh[k].label);}
+ swit1(iqh, nh, def, vr[1]);
}
void
diff --git a/sys/src/cmd/cc/sub.c b/sys/src/cmd/cc/sub.c
index 46e0cada0..e82c3ad31 100644
--- a/sys/src/cmd/cc/sub.c
+++ b/sys/src/cmd/cc/sub.c
@@ -1485,6 +1485,7 @@ Init onamesinit[] =
OINDEX, 0, "INDEX",
OFAS, 0, "FAS",
OREGPAIR, 0, "REGPAIR",
+ OEXREG, 0, "EXREG",
OEND, 0, "END",
-1, 0, 0,
};
@@ -1951,6 +1952,7 @@ tinit(void)
/* 32-bit defaults */
typeword = typechlp;
+ typeswitch = typechl;
typecmplx = typesuv;
}