# HG changeset patch # User David du Colombier <0intro@gmail.com> # Date 1331210743 -3600 # Node ID 66593baf795eb8631799d01be7c2ebdb3a710ea9 # Parent 44eb037cdac3d186e9aa604a2ba3b2f6638c58bd nix: sync with plan 9 R=nixiedev, nemo CC=nix-dev http://codereview.appspot.com/5787052 Committer: Francisco J Ballesteros diff -r 44eb037cdac3 -r 66593baf795e sys/man/1/2c --- a/sys/man/1/2c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/man/1/2c Thu Mar 08 13:45:43 2012 +0100 @@ -488,13 +488,6 @@ No new features of C11, the 2011 ANSI C standard, are implemented. .PP -.B switch -expressions may not be either signedness of -.B vlong -on 32-bit architectures -.RI ( 8c -at least). -.PP The implementation of .B vlong assignment can use a static location diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/6c/txt.c --- a/sys/src/cmd/6c/txt.c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/6c/txt.c Thu Mar 08 13:45:43 2012 +0100 @@ -23,6 +23,7 @@ tfield = types[TINT]; typeword = typechlvp; + typeswitch = typechlv; typecmplx = typesu; /* TO DO */ diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/8c/gc.h --- a/sys/src/cmd/8c/gc.h Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/8c/gc.h Thu Mar 08 13:45:43 2012 +0100 @@ -61,7 +61,7 @@ struct Case { Case* link; - long val; + vlong val; long label; char def; char isv; @@ -70,7 +70,7 @@ struct C1 { - long val; + vlong val; long label; }; diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/8c/swt.c --- a/sys/src/cmd/8c/swt.c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/8c/swt.c Thu Mar 08 13:45:43 2012 +0100 @@ -10,7 +10,7 @@ if(nc < 5) { for(i=0; ival); + print("case = %.8llux\n", q->val); gopcode(OEQ, n->type, n, nodconst(q->val)); patch(p, q->label); q++; @@ -22,7 +22,7 @@ i = nc / 2; r = q+i; if(debug['W']) - print("case > %.8lux\n", r->val); + print("case > %.8llux\n", r->val); gopcode(OGT, n->type, n, nodconst(r->val)); sp = p; gbranch(OGOTO); @@ -31,7 +31,7 @@ swit1(q, i, def, n); if(debug['W']) - print("case < %.8lux\n", r->val); + print("case < %.8llux\n", r->val); patch(sp, pc); swit1(r+1, nc-i-1, def, n); } diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/8c/txt.c --- a/sys/src/cmd/8c/txt.c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/8c/txt.c Thu Mar 08 13:45:43 2012 +0100 @@ -22,6 +22,8 @@ lastp = P; tfield = types[TLONG]; + typeswitch = typechlv; + zprog.link = P; zprog.as = AGOK; zprog.from.type = D_NONE; @@ -314,9 +316,29 @@ case TFLOAT: case TDOUBLE: - case TVLONG: i = D_F0; goto out; + + case TVLONG: + case TUVLONG: + n->op = OREGPAIR; + n->complex = 0; /* already in registers */ + n->addable = 11; + n->type = tn->type; + n->lineno = nearln; + n->left = alloc(sizeof(Node)); + n->right = alloc(sizeof(Node)); + if(o != Z && o->op == OREGPAIR) { + regalloc(n->left, ®node, o->left); + regalloc(n->right, ®node, o->right); + } else { + regalloc(n->left, ®node, Z); + regalloc(n->right, ®node, Z); + } + n->right->type = types[TULONG]; + if(tn->type->etype == TUVLONG) + n->left->type = types[TULONG]; + return; } diag(tn, "unknown type in regalloc: %T", tn->type); err: @@ -343,6 +365,12 @@ { int i; + if(n->op == OREGPAIR) { + regfree(n->left); + regfree(n->right); + return; + } + i = 0; if(n->op != OREGISTER && n->op != OINDREG) goto err; @@ -618,9 +646,6 @@ case TDOUBLE: gins(AFMOVD, f, t); return; - case TVLONG: - gins(AFMOVV, f, t); - return; } /* @@ -659,9 +684,6 @@ case TDOUBLE: gins(AFMOVDP, f, t); return; - case TVLONG: - gins(AFMOVVP, f, t); - return; } /* @@ -989,7 +1011,7 @@ if(et == TFLOAT) a = AFADDF; else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFADDD; if(pop) a = AFADDDP; @@ -1003,7 +1025,7 @@ if(rev) a = AFSUBRF; } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFSUBD; if(pop) a = AFSUBDP; @@ -1020,7 +1042,7 @@ if(et == TFLOAT) a = AFMULF; else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFMULD; if(pop) a = AFMULDP; @@ -1036,7 +1058,7 @@ if(rev) a = AFDIVRF; } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFDIVD; if(pop) a = AFDIVDP; @@ -1063,7 +1085,7 @@ a = AGOK; } } else - if(et == TDOUBLE || et == TVLONG) { + if(et == TDOUBLE) { a = AFCOMF; if(pop) { a = AFCOMDP; diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/cc/cc.h --- a/sys/src/cmd/cc/cc.h Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/cc/cc.h Thu Mar 08 13:45:43 2012 +0100 @@ -515,6 +515,7 @@ extern char typechlp[]; extern char typechlpfd[]; +EXTERN char* typeswitch; EXTERN char* typeword; EXTERN char* typecmplx; diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/cc/pgen.c --- a/sys/src/cmd/cc/pgen.c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/cc/pgen.c Thu Mar 08 13:45:43 2012 +0100 @@ -70,8 +70,12 @@ 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); @@ -267,16 +271,15 @@ 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: @@ -284,7 +287,7 @@ 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; } diff -r 44eb037cdac3 -r 66593baf795e sys/src/cmd/cc/pswt.c --- a/sys/src/cmd/cc/pswt.c Fri Mar 09 10:48:11 2012 +0000 +++ b/sys/src/cmd/cc/pswt.c Thu Mar 08 13:45:43 2012 +0100 @@ -16,8 +16,10 @@ 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 @@ 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 @@ 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> 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