diff options
| author | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
|---|---|---|
| committer | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
| commit | 45a20ab721a513710138340faff3d59a31c3e01e (patch) | |
| tree | eea29d2684c51cc73725b8992a2125bede48e118 /utils/cc | |
| parent | cd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff) | |
sync compilers with Plan 9
remove 1[acl] 2[acl]
Diffstat (limited to 'utils/cc')
| -rw-r--r-- | utils/cc/acid.c | 4 | ||||
| -rw-r--r-- | utils/cc/cc.h | 28 | ||||
| -rw-r--r-- | utils/cc/cc.y | 30 | ||||
| -rw-r--r-- | utils/cc/com.c | 126 | ||||
| -rw-r--r-- | utils/cc/com64.c | 2 | ||||
| -rw-r--r-- | utils/cc/dcl.c | 10 | ||||
| -rw-r--r-- | utils/cc/dpchk.c | 2 | ||||
| -rw-r--r-- | utils/cc/lex.c | 37 | ||||
| -rw-r--r-- | utils/cc/lexbody | 6 | ||||
| -rw-r--r-- | utils/cc/macbody | 4 | ||||
| -rw-r--r-- | utils/cc/pgen.c | 70 | ||||
| -rw-r--r-- | utils/cc/pickle.c | 2 | ||||
| -rw-r--r-- | utils/cc/pswt.c | 85 | ||||
| -rw-r--r-- | utils/cc/scon.c | 4 | ||||
| -rw-r--r-- | utils/cc/sub.c | 38 |
15 files changed, 356 insertions, 92 deletions
diff --git a/utils/cc/acid.c b/utils/cc/acid.c index 3d898883..d42b47b4 100644 --- a/utils/cc/acid.c +++ b/utils/cc/acid.c @@ -2,7 +2,7 @@ static char *kwd[] = { - "$adt", "$aggr", "$append", "$complex", "$defn", + "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", "$delete", "$do", "$else", "$eval", "$head", "$if", "$local", "$loop", "$return", "$tail", "$then", "$union", "$whatis", "$while", @@ -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/utils/cc/cc.h b/utils/cc/cc.h index 2813d25f..23b1c24b 100644 --- a/utils/cc/cc.h +++ b/utils/cc/cc.h @@ -17,17 +17,19 @@ typedef struct Term Term; typedef struct Init Init; typedef struct Bits Bits; +typedef Rune TRune; /* target system type */ + #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) ((uvlong)1<<(n-1)) #define MASK(n) (SIGN(n)|(SIGN(n)-1)) #define BITS 5 @@ -48,7 +50,7 @@ struct Node double fconst; /* fp constant */ vlong vconst; /* non fp const */ char* cstring; /* character string */ - ushort* rstring; /* rune string */ + TRune* rstring; /* rune string */ Sym* sym; Type* type; @@ -292,6 +294,7 @@ enum OINDEX, OFAS, OREGPAIR, + OEXREG, OEND }; @@ -333,6 +336,9 @@ enum TFILE, TOLD, NALLTYPES, + + /* adapt size of Rune to target system's size */ + TRUNE = sizeof(TRune)==4? TUINT: TUSHORT, }; enum { @@ -475,6 +481,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; @@ -504,6 +511,7 @@ extern char typechlv[]; extern char typechlvp[]; extern char typechlp[]; extern char typechlpfd[]; +EXTERN char* typeswitch; EXTERN char* typeword; EXTERN char* typecmplx; @@ -617,7 +625,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*); @@ -635,6 +643,8 @@ int tcomo(Node*, int); int tcomx(Node*); int tlvalue(Node*); void constas(Node*, Type*, Type*); +Node* uncomma(Node*); +Node* uncomargs(Node*); /* * con.c @@ -642,8 +652,8 @@ void constas(Node*, Type*, Type*); void acom(Node*); void acom1(vlong, Node*); void acom2(Node*, Type*); -int acomcmp1(const void*, const void*); -int acomcmp2(const void*, const void*); +int acomcmp1(void*, void*); +int acomcmp2(void*, void*); int addo(Node*); void evconst(Node*); @@ -657,6 +667,7 @@ void dclfunct(Type*, Sym*); * sub.c */ void arith(Node*, int); +int castucom(Node*); int deadheads(Node*); Type* dotsearch(Sym*, Type*, Node*, long*); long dotoffset(Type*, Type*, Node*); @@ -738,8 +749,7 @@ void gclean(void); void gextern(Sym*, Node*, long, long); void ginit(void); long outstring(char*, long); -long outlstring(ushort*, long); -void sextern(Sym*, Node*, long, long); +long outlstring(TRune*, long); void xcom(Node*); long exreg(Type*); long align(long, Type*, int); diff --git a/utils/cc/cc.y b/utils/cc/cc.y index 3057547b..8c9d09b1 100644 --- a/utils/cc/cc.y +++ b/utils/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 { @@ -853,9 +855,9 @@ lstring: LLSTRING { $$ = new(OLSTRING, Z, Z); - $$->type = typ(TARRAY, types[TUSHORT]); - $$->type->width = $1.l + sizeof(ushort); - $$->rstring = (ushort*)$1.s; + $$->type = typ(TARRAY, types[TRUNE]); + $$->type->width = $1.l + sizeof(TRune); + $$->rstring = (TRune*)$1.s; $$->sym = symstring; $$->etype = TARRAY; $$->class = CSTATIC; @@ -865,16 +867,16 @@ lstring: char *s; int n; - n = $1->type->width - sizeof(ushort); + n = $1->type->width - sizeof(TRune); s = alloc(n+$2.l+MAXALIGN); memcpy(s, $1->rstring, n); memcpy(s+n, $2.s, $2.l); - *(ushort*)(s+n+$2.l) = 0; + *(TRune*)(s+n+$2.l) = 0; $$ = $1; $$->type->width += $2.l; - $$->rstring = (ushort*)s; + $$->rstring = (TRune*)s; } zelist: @@ -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/utils/cc/com.c b/utils/cc/com.c index 59a7bd06..3a7f29d0 100644 --- a/utils/cc/com.c +++ b/utils/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"); @@ -56,6 +67,7 @@ tcomo(Node *n, int f) Node *l, *r; Type *t; int o; + static TRune zer; if(n == Z) { diag(Z, "Z in tcom"); @@ -273,8 +285,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 +625,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; @@ -617,10 +634,10 @@ tcomo(Node *n, int f) break; case OLSTRING: - if(n->type->link != types[TUSHORT]) { + if(n->type->link != types[TRUNE]) { o = outstring(0, 0); while(o & 3) { - outlstring(L"", sizeof(ushort)); + outlstring(&zer, sizeof(TRune)); o = outlstring(0, 0); } } @@ -882,6 +899,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 @@ -928,13 +1040,16 @@ loop: break; case OCAST: + if(castucom(n)) + warn(n, "32-bit unsigned complement zero-extended to 64 bits"); ccom(l); if(l->op == OCONST) { evconst(n); 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 +1457,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/utils/cc/com64.c b/utils/cc/com64.c index e1f7c8a3..f44a44ff 100644 --- a/utils/cc/com64.c +++ b/utils/cc/com64.c @@ -274,6 +274,8 @@ com64(Node *n) case ORETURN: case OAS: case OIND: + case OLIST: + case OCOMMA: return 1; case OADD: a = nodaddv; diff --git a/utils/cc/dcl.c b/utils/cc/dcl.c index 6a8e7245..c6b762a6 100644 --- a/utils/cc/dcl.c +++ b/utils/cc/dcl.c @@ -232,7 +232,7 @@ nextinit(void) a->cstring++; } if(a->op == OLSTRING) { - b->vconst = convvtox(*a->rstring, TUSHORT); + b->vconst = convvtox(*a->rstring, TRUNE); a->rstring++; } a->type->width -= b->type->width; @@ -519,7 +519,7 @@ newlist(Node *l, Node *r) } void -suallign(Type *t) +sualign(Type *t) { Type *l; long o, w; @@ -540,8 +540,8 @@ suallign(Type *t) } l->offset = o; } else { - if(l->width <= 0) - if(l->down != T) + if(l->width < 0 || + l->width == 0 && l->down != T) if(l->sym) diag(Z, "incomplete structure element: %s", l->sym->name); @@ -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; } } diff --git a/utils/cc/dpchk.c b/utils/cc/dpchk.c index 99a49ee5..011f9c8a 100644 --- a/utils/cc/dpchk.c +++ b/utils/cc/dpchk.c @@ -75,9 +75,9 @@ getflag(char *s) nstar = 0; for(;;) { s += chartorune(&c, s); - fmt += runetochar(fmt, &c); if(c == 0 || c >= nelem(flagbits)) break; + fmt += runetochar(fmt, &c); f = flagbits[c]; switch(f) { case Fnone: diff --git a/utils/cc/lex.c b/utils/cc/lex.c index 8ba5af5a..9aae5c2b 100644 --- a/utils/cc/lex.c +++ b/utils/cc/lex.c @@ -80,7 +80,8 @@ main(int argc, char *argv[]) case 'I': p = ARGF(); - setinclude(p); + if(p) + setinclude(p); break; } ARGEND if(argc < 1 && outfile == 0) { @@ -242,14 +243,10 @@ compile(char *file, char **defs, int ndef) close(fd[1]); av[0] = CPP; i = 1; - if(debug['.']){ - sprint(opt, "-."); - av[i++] = strdup(opt); - } - if(debug['+']) { - sprint(opt, "-+"); - av[i++] = strdup(opt); - } + if(debug['.']) + av[i++] = strdup("-."); + /* 1999 ANSI C requires recognising // comments */ + av[i++] = strdup("-+"); for(c = 0; c < ndef; c++) { sprint(opt, "-D%s", defs[c]); av[i++] = strdup(opt); @@ -469,7 +466,7 @@ l1: yyerror("missing '"); peekc = c1; } - yylval.vval = convvtox(c, TUSHORT); + yylval.vval = convvtox(c, TRUNE); return LUCONST; } if(c == '"') { @@ -543,15 +540,15 @@ l1: c = escchar('"', 1, 0); if(c == EOF) break; - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = c; - c1 += sizeof(ushort); + cp = allocn(cp, c1, sizeof(TRune)); + *(TRune*)(cp + c1) = c; + c1 += sizeof(TRune); } yylval.sval.l = c1; do { - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = 0; - c1 += sizeof(ushort); + cp = allocn(cp, c1, sizeof(TRune)); + *(TRune*)(cp + c1) = 0; + c1 += sizeof(TRune); } while(c1 & MAXALIGN); yylval.sval.s = cp; return LLSTRING; @@ -1028,7 +1025,7 @@ getnsc(void) } else c = GETC(); for(;;) { - if(!isspace(c)) + if(c >= Runeself || !isspace(c)) return c; if(c == '\n') { lineno++; @@ -1072,7 +1069,7 @@ loop: */ i = 2; if(longflg) - i = 4; + i = 6; l = 0; for(; i>0; i--) { c = getc(); @@ -1102,7 +1099,7 @@ loop: */ i = 2; if(longflg) - i = 5; + i = 8; l = c - '0'; for(; i>0; i--) { c = getc(); @@ -1238,7 +1235,7 @@ cinit(void) if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) - strcpy(pathname, "/???"); + strcpy(pathname, "/?"); } fmtinstall('O', Oconv); diff --git a/utils/cc/lexbody b/utils/cc/lexbody index 6b226ada..d8e3f6eb 100644 --- a/utils/cc/lexbody +++ b/utils/cc/lexbody @@ -417,8 +417,10 @@ l1: if(c1 == '/') { for(;;) { c = GETC(); - if(c == '\n') - goto l1; + if(c == '\n') { + lineno++; + goto l0; + } if(c == EOF) { yyerror("eof in comment"); errorexit(); diff --git a/utils/cc/macbody b/utils/cc/macbody index e26dc427..7c86bac1 100644 --- a/utils/cc/macbody +++ b/utils/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/utils/cc/pgen.c b/utils/cc/pgen.c index 131ff012..a5f67df2 100644 --- a/utils/cc/pgen.c +++ b/utils/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,19 @@ bcomplex(Node *n, Node *c) } if(c != Z && n->op == OCONST && deadheads(c)) return 1; + if(newvlongcode && typev[n->type->etype] && machcap(Z)) { + nod = znode; + 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]; + xcom(b); + boolgen(b, 1, Z); + return 0; + } bool64(n); boolgen(n, 1, Z); return 0; diff --git a/utils/cc/pickle.c b/utils/cc/pickle.c index ef8df4c0..1946b4e6 100644 --- a/utils/cc/pickle.c +++ b/utils/cc/pickle.c @@ -2,7 +2,7 @@ static char *kwd[] = { - "$adt", "$aggr", "$append", "$complex", "$defn", + "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn", "$delete", "$do", "$else", "$eval", "$head", "$if", "$local", "$loop", "$return", "$tail", "$then", "$union", "$whatis", "$while", diff --git a/utils/cc/pswt.c b/utils/cc/pswt.c index 6ef4f2fb..0471c10d 100644 --- a/utils/cc/pswt.c +++ b/utils/cc/pswt.c @@ -1,7 +1,7 @@ #include "gc.h" int -swcmp(const void *a1, const void *a2) +swcmp(void *a1, void *a2) { C1 *p1, *p2; @@ -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; @@ -49,7 +57,7 @@ doswit(Node *n) q++; } qsort(iq, nc, sizeof(C1), swcmp); - if(debug['W']) + if(debug['K']) for(i=0; i<nc; i++) print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val); dup = 0; @@ -64,7 +72,51 @@ 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); + iqh[nh].label = pc; + nh++; + swit1(iql, q-iql, def, vr[0]); + i = j; + } + patch(hsb, pc); + swit1(iqh, nh, def, vr[1]); } void @@ -78,28 +130,29 @@ casf(void) } long -outlstring(ushort *s, long n) +outlstring(TRune *s, long n) { - char buf[2]; - int c; + char buf[sizeof(TRune)]; + uint c; + int i; long r; if(suppress) return nstring; - while(nstring & 1) + while(nstring & (sizeof(TRune)-1)) outstring("", 1); r = nstring; while(n > 0) { c = *s++; if(align(0, types[TCHAR], Aarg1)) { - buf[0] = c>>8; - buf[1] = c; + for(i = 0; i < sizeof(TRune); i++) + buf[i] = c>>(8*(sizeof(TRune) - i - 1)); } else { - buf[0] = c; - buf[1] = c>>8; + for(i = 0; i < sizeof(TRune); i++) + buf[i] = c>>(8*i); } - outstring(buf, 2); - n -= sizeof(ushort); + outstring(buf, sizeof(TRune)); + n -= sizeof(TRune); } return r; } diff --git a/utils/cc/scon.c b/utils/cc/scon.c index f0c2bd13..0a15885c 100644 --- a/utils/cc/scon.c +++ b/utils/cc/scon.c @@ -309,7 +309,7 @@ acom(Node *n) } int -acomcmp1(const void *a1, const void *a2) +acomcmp1(void *a1, void *a2) { vlong c1, c2; Term *t1, *t2; @@ -340,7 +340,7 @@ acomcmp1(const void *a1, const void *a2) } int -acomcmp2(const void *a1, const void *a2) +acomcmp2(void *a1, void *a2) { vlong c1, c2; Term *t1, *t2; diff --git a/utils/cc/sub.c b/utils/cc/sub.c index 46e0cada..441b0c7f 100644 --- a/utils/cc/sub.c +++ b/utils/cc/sub.c @@ -85,7 +85,10 @@ prtree1(Node *n, int d, int f) break; case OLSTRING: - print(" \"%S\"", n->rstring); + if(sizeof(TRune) == sizeof(Rune)) + print(" \"%S\"", (Rune*)n->rstring); + else + print(" \"...\""); i = 0; break; @@ -914,6 +917,10 @@ loop: case ONOT: case OADDR: case OIND: + case OCOM: + case ONEG: + case OPOS: + case OTST: n = n->left; goto loop; @@ -1187,12 +1194,15 @@ warn(Node *n, char *fmt, ...) char buf[STRINGSZ]; va_list arg; - if(debug['w']) { - Bprint(&diagbuf, "warning: "); + if(debug['w'] || debug['W']) { va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); + if(debug['W']) { + diag(n, "%s", buf); + return; + } + Bprint(&diagbuf, "warning: %L %s\n", (n==Z)? nearln: n->lineno, buf); if(n != Z) if(debug['v']) @@ -1485,6 +1495,7 @@ Init onamesinit[] = OINDEX, 0, "INDEX", OFAS, 0, "FAS", OREGPAIR, 0, "REGPAIR", + OEXREG, 0, "EXREG", OEND, 0, "END", -1, 0, 0, }; @@ -1951,6 +1962,7 @@ tinit(void) /* 32-bit defaults */ typeword = typechlp; + typeswitch = typechl; typecmplx = typesuv; } @@ -2022,3 +2034,21 @@ mixedasop(Type *l, Type *r) { return !typefd[l->etype] && typefd[r->etype]; } + + +/* + * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong + * an explicit cast to ulong after ~ suppresses the diagnostic + */ +int +castucom(Node *r) +{ + Node *rl; + + if(r->op == OCAST && + (rl = r->left)->op == OCOM && + (r->type->etype == TVLONG || r->type->etype == TUVLONG) && + typeu[rl->type->etype] && typechl[rl->type->etype]) + return 1; + return 0; +} |
