diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-30 19:11:16 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-30 19:11:16 +0200 |
commit | 4f33c88a51587681b7be1ae57cfbc43b627c6bc4 (patch) | |
tree | 25560404dc80007e5dc268811242c9071f6a1017 /sys/src/cmd/cc | |
parent | fcc5e75d07e5bc6cb3ddac6d9a437e7ec62d0d95 (diff) |
import updated compilers from sources
Diffstat (limited to 'sys/src/cmd/cc')
-rw-r--r-- | sys/src/cmd/cc/acid.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/cc/cc.h | 13 | ||||
-rw-r--r-- | sys/src/cmd/cc/cc.y | 18 | ||||
-rw-r--r-- | sys/src/cmd/cc/com.c | 119 | ||||
-rw-r--r-- | sys/src/cmd/cc/com64.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/cc/dcl.c | 12 | ||||
-rw-r--r-- | sys/src/cmd/cc/lex.c | 4 | ||||
-rw-r--r-- | sys/src/cmd/cc/macbody | 4 | ||||
-rw-r--r-- | sys/src/cmd/cc/pgen.c | 69 | ||||
-rw-r--r-- | sys/src/cmd/cc/pswt.c | 62 | ||||
-rw-r--r-- | sys/src/cmd/cc/sub.c | 2 |
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; } |