History

20100427-2208

forsyth committed 16 years ago

Commit 46e88df1 parent a8d33fe18 files · +142 −1542Browse files

Unified · Split

18 files
  1. utils/5c/5.out.h +3 −1
  2. utils/5c/cgen.c +58 −46
  3. utils/5c/gc.h +6 −3
  4. utils/5c/mkfile +8 −0
  5. utils/5c/reg.c +5 −4
  6. utils/5c/sgen.c +0 −394
  7. utils/5c/swt.c +8 −129
  8. utils/5c/txt.c +5 −5
  9. utils/kc/gc.h +6 −3
  10. utils/kc/mkfile +8 −0
  11. utils/kc/sgen.c +0 −352
  12. utils/kc/swt.c +6 −122
  13. utils/vc/cgen.c +2 −0
  14. utils/vc/gc.h +6 −3
  15. utils/vc/mkfile +8 −0
  16. utils/vc/peep.c +1 −1
  17. utils/vc/sgen.c +0 −353
  18. utils/vc/swt.c +12 −126
utils/5c/5.out.h+3−1
@@ -9,7 +9,9 @@ · 8 unmodified lines
99 #define REGRET 0
1010 #define REGARG 0
1111 /* compiler allocates R1 up as temps */
12−/* compiler allocates register variables R3 up */
12+/* compiler allocates register variables R2 up */
13+#define REGMIN 2
14+#define REGMAX 8
1315 #define REGEXT 10
1416 /* compiler allocates external registers R10 down */
1517 #define REGTMP 11
utils/5c/cgen.c+58−46
@@ -1,7 +1,13 @@
11 #include "gc.h"
22
33 void
4−cgen(Node *n, Node *nn, int inrel)
4+cgen(Node *n, Node *nn)
5+{
6+ cgenrel(n, nn, 0);
7+}
8+
9+void
10+cgenrel(Node *n, Node *nn, int inrel)
511 {
612 Node *l, *r;
713 Prog *p1;
@@ -45,7 +51,7 @@ cgen(Node *n, Node *nn, int inrel) · 37 unmodified lines
4551 switch(o) {
4652 default:
4753 regret(&nod, r);
48− cgen(r, &nod, 0);
54+ cgen(r, &nod);
4955
5056 regsalloc(&nod1, r);
5157 gopcode(OAS, &nod, Z, &nod1);
@@ -53,7 +59,7 @@ cgen(Node *n, Node *nn, int inrel) · 1 unmodified line
5359 regfree(&nod);
5460 nod = *n;
5561 nod.right = &nod1;
56− cgen(&nod, nn, 0);
62+ cgen(&nod, nn);
5763 return;
5864
5965 case OFUNC:
@@ -79,7 +85,7 @@ cgen(Node *n, Node *nn, int inrel) · 19 unmodified lines
7985 regret(&nod, r);
8086 else
8187 regalloc(&nod, r, nn);
82− cgen(r, &nod, 0);
88+ cgen(r, &nod);
8389 gmove(&nod, l);
8490 if(nn != Z)
8591 gmove(&nod, nn);
@@ -98,10 +104,10 @@ cgen(Node *n, Node *nn, int inrel) · 12 unmodified lines
98104 break;
99105 }
100106 regalloc(&nod, r, nn);
101− cgen(r, &nod, 0);
107+ cgen(r, &nod);
102108 } else {
103109 regalloc(&nod, r, nn);
104− cgen(r, &nod, 0);
110+ cgen(r, &nod);
105111 reglcgen(&nod1, l, Z);
106112 }
107113 gmove(&nod, &nod1);
@@ -114,9 +120,9 @@ cgen(Node *n, Node *nn, int inrel) · 6 unmodified lines
114120 regalloc(&nod, r, nn);
115121 if(l->complex >= r->complex) {
116122 reglcgen(&nod1, n, Z);
117− cgen(r, &nod, 0);
123+ cgen(r, &nod);
118124 } else {
119− cgen(r, &nod, 0);
125+ cgen(r, &nod);
120126 reglcgen(&nod1, n, Z);
121127 }
122128 regalloc(&nod2, n, Z);
@@ -139,7 +145,7 @@ cgen(Node *n, Node *nn, int inrel) · 16 unmodified lines
139145 if(nn != Z)
140146 if((t = vlog(r)) >= 0) {
141147 /* signed div/mod by constant power of 2 */
142− cgen(l, nn, 0);
148+ cgen(l, nn);
143149 gopcode(OGE, nodconst(0), nn, Z);
144150 p1 = p;
145151 if(o == ODIV) {
@@ -164,7 +170,7 @@ cgen(Node *n, Node *nn, int inrel) · 18 unmodified lines
164170 if(nn != Z)
165171 if(l->op == OCONST)
166172 if(!typefd[n->type->etype]) {
167− cgen(r, nn, 0);
173+ cgen(r, nn);
168174 gopcode(o, Z, l, nn);
169175 break;
170176 }
@@ -181,7 +187,7 @@ cgen(Node *n, Node *nn, int inrel) · 10 unmodified lines
181187 if(nn != Z)
182188 if(r->op == OCONST)
183189 if(!typefd[n->type->etype]) {
184− cgen(l, nn, 0);
190+ cgen(l, nn);
185191 if(r->vconst == 0)
186192 if(o != OAND)
187193 break;
@@ -205,15 +211,15 @@ cgen(Node *n, Node *nn, int inrel) · 17 unmodified lines
205211 }
206212 if(l->complex >= r->complex) {
207213 regalloc(&nod, l, nn);
208− cgen(l, &nod, 0);
214+ cgen(l, &nod);
209215 regalloc(&nod1, r, Z);
210− cgen(r, &nod1, 0);
216+ cgen(r, &nod1);
211217 gopcode(o, &nod1, Z, &nod);
212218 } else {
213219 regalloc(&nod, r, nn);
214− cgen(r, &nod, 0);
220+ cgen(r, &nod);
215221 regalloc(&nod1, l, Z);
216− cgen(l, &nod1, 0);
222+ cgen(l, &nod1);
217223 gopcode(o, &nod, &nod1, &nod);
218224 }
219225 gopcode(OAS, &nod, Z, nn);
@@ -263,10 +269,10 @@ cgen(Node *n, Node *nn, int inrel) · 43 unmodified lines
263269 else
264270 nod2 = *l;
265271 regalloc(&nod1, r, Z);
266− cgen(r, &nod1, 0);
272+ cgen(r, &nod1);
267273 } else {
268274 regalloc(&nod1, r, Z);
269− cgen(r, &nod1, 0);
275+ cgen(r, &nod1);
270276 if(l->addable < INDEXED)
271277 reglcgen(&nod2, l, Z);
272278 else
@@ -290,10 +296,10 @@ cgen(Node *n, Node *nn, int inrel) · 17 unmodified lines
290296 if(l->complex >= r->complex) {
291297 bitload(l, &nod, &nod1, &nod2, &nod4);
292298 regalloc(&nod3, r, Z);
293− cgen(r, &nod3, 0);
299+ cgen(r, &nod3);
294300 } else {
295301 regalloc(&nod3, r, Z);
296− cgen(r, &nod3, 0);
302+ cgen(r, &nod3);
297303 bitload(l, &nod, &nod1, &nod2, &nod4);
298304 }
299305 gmove(&nod, &nod4);
@@ -318,7 +324,7 @@ cgen(Node *n, Node *nn, int inrel) · 18 unmodified lines
318324 diag(n, "bad function call");
319325
320326 regret(&nod, l->left);
321− cgen(l->left, &nod, 0);
327+ cgen(l->left, &nod);
322328 regsalloc(&nod1, l->left);
323329 gopcode(OAS, &nod, Z, &nod1);
324330 regfree(&nod);
@@ -328,7 +334,7 @@ cgen(Node *n, Node *nn, int inrel) · 3 unmodified lines
328334 nod2 = *l;
329335 nod2.left = &nod1;
330336 nod2.complex = 1;
331− cgen(&nod, nn, 0);
337+ cgen(&nod, nn);
332338
333339 return;
334340 }
@@ -363,11 +369,11 @@ cgen(Node *n, Node *nn, int inrel) · 28 unmodified lines
363369 if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) {
364370 v = r->vconst;
365371 r->vconst = 0;
366− cgen(l, &nod, 0);
372+ cgen(l, &nod);
367373 nod.xoffset += v;
368374 r->vconst = v;
369375 } else
370− cgen(l, &nod, 0);
376+ cgen(l, &nod);
371377 regind(&nod, n);
372378 gopcode(OAS, &nod, Z, nn);
373379 regfree(&nod);
@@ -406,8 +412,8 @@ cgen(Node *n, Node *nn, int inrel) · 32 unmodified lines
406412 break;
407413
408414 case OCOMMA:
409− cgen(l, Z, 0);
410− cgen(r, nn, 0);
415+ cgen(l, Z);
416+ cgen(r, nn);
411417 break;
412418
413419 case OCAST:
@@ -420,12 +426,12 @@ cgen(Node *n, Node *nn, int inrel) · 6 unmodified lines
420426 */
421427 if(nocast(l->type, n->type)) {
422428 if(nocast(n->type, nn->type)) {
423− cgen(l, nn, 0);
429+ cgen(l, nn);
424430 break;
425431 }
426432 }
427433 regalloc(&nod, l, nn);
428− cgen(l, &nod, 0);
434+ cgen(l, &nod);
429435 regalloc(&nod1, n, &nod);
430436 if(inrel)
431437 gmover(&nod, &nod1);
@@ -447,18 +453,18 @@ cgen(Node *n, Node *nn, int inrel) · 15 unmodified lines
447453 }
448454 nod.xoffset += (long)r->vconst;
449455 nod.type = n->type;
450− cgen(&nod, nn, 0);
456+ cgen(&nod, nn);
451457 }
452458 break;
453459
454460 case OCOND:
455461 bcgen(l, 1);
456462 p1 = p;
457− cgen(r->left, nn, 0);
463+ cgen(r->left, nn);
458464 gbranch(OGOTO);
459465 patch(p1, pc);
460466 p1 = p;
461− cgen(r->right, nn, 0);
467+ cgen(r->right, nn);
462468 patch(p1, pc);
463469 break;
464470
@@ -533,6 +539,8 @@ cgen(Node *n, Node *nn, int inrel) · 68 unmodified lines
533539 } else
534540 gopcode(OADD, nodconst(v), Z, &nod);
535541 gopcode(OAS, &nod, Z, &nod2);
542+ if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
543+ gins(ANOP, l, Z);
536544
537545 regfree(&nod);
538546 if(l->addable < INDEXED)
@@ -579,7 +587,7 @@ reglcgen(Node *t, Node *n, Node *nn) · 40 unmodified lines
579587 } else if(n->op == OINDREG) {
580588 if((v = n->xoffset) > -4096 && v < 4096) {
581589 n->op = OREGISTER;
582− cgen(n, t, 0);
590+ cgen(n, t);
583591 t->xoffset += v;
584592 n->op = OINDREG;
585593 regind(t, n);
@@ -638,12 +646,12 @@ lcgen(Node *n, Node *nn) · 52 unmodified lines
638646 break;
639647
640648 case OCOMMA:
641− cgen(n->left, n->left, 0);
649+ cgen(n->left, n->left);
642650 lcgen(n->right, nn);
643651 break;
644652
645653 case OIND:
646− cgen(n->left, nn, 0);
654+ cgen(n->left, nn);
647655 break;
648656
649657 case OCOND:
@@ -688,7 +696,7 @@ boolgen(Node *n, int true, Node *nn) · 38 unmodified lines
688696
689697 default:
690698 regalloc(&nod, n, nn);
691− cgen(n, &nod, 0);
699+ cgen(n, &nod);
692700 o = ONE;
693701 if(true)
694702 o = comrel[relindex(o)];
@@ -712,7 +720,7 @@ boolgen(Node *n, int true, Node *nn) · 17 unmodified lines
712720 goto com;
713721
714722 case OCOMMA:
715− cgen(l, Z, 0);
723+ cgen(l, Z);
716724 boolgen(r, true, nn);
717725 break;
718726
@@ -779,7 +787,7 @@ boolgen(Node *n, int true, Node *nn) · 60 unmodified lines
779787 o = comrel[relindex(o)];
780788 if(l->complex >= FNX && r->complex >= FNX) {
781789 regret(&nod, r);
782− cgen(r, &nod, 1);
790+ cgenrel(r, &nod, 1);
783791 regsalloc(&nod1, r);
784792 gopcode(OAS, &nod, Z, &nod1);
785793 regfree(&nod);
@@ -790,7 +798,7 @@ boolgen(Node *n, int true, Node *nn) · 4 unmodified lines
790798 }
791799 if(sconst(l)) {
792800 regalloc(&nod, r, nn);
793− cgen(r, &nod, 1);
801+ cgenrel(r, &nod, 1);
794802 o = invrel[relindex(o)];
795803 gopcode(o, l, &nod, Z);
796804 regfree(&nod);
@@ -798,21 +806,21 @@ boolgen(Node *n, int true, Node *nn) · 1 unmodified line
798806 }
799807 if(sconst(r)) {
800808 regalloc(&nod, l, nn);
801− cgen(l, &nod, 1);
809+ cgenrel(l, &nod, 1);
802810 gopcode(o, r, &nod, Z);
803811 regfree(&nod);
804812 goto com;
805813 }
806814 if(l->complex >= r->complex) {
807815 regalloc(&nod1, l, nn);
808− cgen(l, &nod1, 1);
816+ cgenrel(l, &nod1, 1);
809817 regalloc(&nod, r, Z);
810− cgen(r, &nod, 1);
818+ cgenrel(r, &nod, 1);
811819 } else {
812820 regalloc(&nod, r, nn);
813− cgen(r, &nod, 1);
821+ cgenrel(r, &nod, 1);
814822 regalloc(&nod1, l, Z);
815− cgen(l, &nod1, 1);
823+ cgenrel(l, &nod1, 1);
816824 }
817825 gopcode(o, &nod, &nod1, Z);
818826 regfree(&nod);
@@ -936,7 +944,7 @@ sugen(Node *n, Node *nn, long w) · 117 unmodified lines
936944 r = r->right;
937945 }
938946 if(nn == Z) {
939− cgen(l, nn, 0);
947+ cgen(l, nn);
940948 continue;
941949 }
942950 /*
@@ -974,7 +982,7 @@ sugen(Node *n, Node *nn, long w) · 31 unmodified lines
974982 xcom(&nod0);
975983 nod0.addable = 0;
976984
977− cgen(&nod0, Z, 0);
985+ cgen(&nod0, Z);
978986 }
979987 break;
980988
@@ -1004,7 +1012,7 @@ sugen(Node *n, Node *nn, long w) · 23 unmodified lines
10041012 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
10051013 n->type = types[TVOID];
10061014 n->left->type = types[TVOID];
1007− cgen(n, Z, 0);
1015+ cgen(n, Z);
10081016 break;
10091017
10101018 case OCOND:
@@ -1019,7 +1027,7 @@ sugen(Node *n, Node *nn, long w) · 8 unmodified lines
10191027 break;
10201028
10211029 case OCOMMA:
1022− cgen(n->left, Z, 0);
1030+ cgen(n->left, Z);
10231031 sugen(n->right, nn, w);
10241032 break;
10251033 }
@@ -1063,6 +1071,10 @@ copy: · 37 unmodified lines
10631071 }
10641072 regalloc(&nod3, &regnode, Z);
10651073 regalloc(&nod4, &regnode, Z);
1074+ if(nod3.reg > nod4.reg){
1075+ /* code below assumes nod3 loaded first */
1076+ Node t = nod3; nod3 = nod4; nod4 = t;
1077+ }
10661078 nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg));
10671079 if(w == 2 && nod1.xoffset == 0)
10681080 gmovm(&nod1, &nod0, 0);
utils/5c/gc.h+6−3
@@ -62,6 +62,7 @@ struct Case · 61 unmodified lines
6262 long val;
6363 long label;
6464 char def;
65+ char isv;
6566 };
6667 #define C ((Case*)0)
6768
@@ -134,6 +135,7 @@ struct Rgn · 66 unmodified lines
134135 };
135136
136137 EXTERN long breakpc;
138+EXTERN long nbreak;
137139 EXTERN Case* cases;
138140 EXTERN Node constnode;
139141 EXTERN Node fconstnode;
@@ -145,7 +147,6 @@ EXTERN Prog* lastp; · 5 unmodified lines
145147 EXTERN long maxargsafe;
146148 EXTERN int mnstring;
147149 EXTERN Multab multab[20];
148−EXTERN int retok;
149150 EXTERN int hintabsize;
150151 EXTERN Node* nodrat;
151152 EXTERN Node* nodret;
@@ -216,7 +217,8 @@ int bcomplex(Node*, Node*); · 64 unmodified lines
216217 /*
217218 * cgen.c
218219 */
219−void cgen(Node*, Node*, int);
220+void cgen(Node*, Node*);
221+void cgenrel(Node*, Node*, int);
220222 void reglcgen(Node*, Node*, Node*);
221223 void lcgen(Node*, Node*);
222224 void bcgen(Node*, int);
@@ -265,7 +267,8 @@ void gpseudo(int, Sym*, Node*); · 42 unmodified lines
265267 */
266268 int swcmp(const void*, const void*);
267269 void doswit(Node*);
268−void swit1(C1*, int, long, Node*, Node*);
270+void swit1(C1*, int, long, Node*);
271+void swit2(C1*, int, long, Node*, Node*);
269272 void casf(void);
270273 void bitload(Node*, Node*, Node*, Node*, Node*);
271274 void bitstore(Node*, Node*, Node*, Node*, Node*);
utils/5c/mkfile+8−0
@@ -8,6 +8,8 @@ OFILES=\ · 7 unmodified lines
88 list.$O\
99 mul.$O\
1010 peep.$O\
11+ pgen.$O\
12+ pswt.$O\
1113 reg.$O\
1214 sgen.$O\
1315 swt.$O\
@@ -28,3 +30,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 14 unmodified lines
2830 cd ../cc
2931 mk $MKFLAGS install
3032 mk $MKFLAGS clean
33+
34+%.$O: ../cc/%.c
35+ $CC $CFLAGS -I. ../cc/$stem.c
36+
37+#enam.c: 5.out.h
38+# rc mkenam
utils/5c/reg.c+5−4
@@ -789,6 +789,7 @@ loopit(Reg *r, long nr) · 788 unmodified lines
789789 idom = alloc(nr * sizeof(long));
790790 maxnr = nr;
791791 }
792+
792793 d = postorder(r, rpo2r, 0);
793794 if(d > nr)
794795 fatal(Z, "too many reg nodes");
@@ -1116,15 +1117,15 @@ long · 321 unmodified lines
11161117 RtoB(int r)
11171118 {
11181119
1119− if(r < 2 || r >= REGTMP)
1120− return 0;
1121− return 1L << r;
1120+ if(r >= REGMIN && r <= REGMAX)
1121+ return 1L << r;
1122+ return 0;
11221123 }
11231124
11241125 int
11251126 BtoR(long b)
11261127 {
1127− b &= 0x07fcL;
1128+ b &= 0x01fcL;
11281129 if(b == 0)
11291130 return 0;
11301131 return bitno(b);
utils/5c/sgen.c+0−394
@@ -1,381 +1,5 @@
11 #include "gc.h"
22
3−void
4−codgen(Node *n, Node *nn)
5−{
6− Prog *sp;
7− Node *n1, nod, nod1;
8−
9− cursafe = 0;
10− curarg = 0;
11− maxargsafe = 0;
12−
13− /*
14− * isolate name
15− */
16− for(n1 = nn;; n1 = n1->left) {
17− if(n1 == Z) {
18− diag(nn, "cant find function name");
19− return;
20− }
21− if(n1->op == ONAME)
22− break;
23− }
24− nearln = nn->lineno;
25− gpseudo(ATEXT, n1->sym, nodconst(stkoff));
26− sp = p;
27−
28− /*
29− * isolate first argument
30− */
31− if(REGARG >= 0) {
32− if(typesuv[thisfn->link->etype]) {
33− nod1 = *nodret->left;
34− nodreg(&nod, &nod1, REGARG);
35− gopcode(OAS, &nod, Z, &nod1);
36− } else
37− if(firstarg && typechlp[firstargtype->etype]) {
38− nod1 = *nodret->left;
39− nod1.sym = firstarg;
40− nod1.type = firstargtype;
41− nod1.xoffset = align(0, firstargtype, Aarg1);
42− nod1.etype = firstargtype->etype;
43− nodreg(&nod, &nod1, REGARG);
44− gopcode(OAS, &nod, Z, &nod1);
45− }
46− }
47−
48− retok = 0;
49− gen(n);
50− if(!retok)
51− if(thisfn->link->etype != TVOID)
52− warn(Z, "no return at end of function: %s", n1->sym->name);
53− noretval(3);
54− gbranch(ORETURN);
55−
56− if(!debug['N'] || debug['R'] || debug['P'])
57− regopt(sp);
58−
59− sp->to.offset += maxargsafe;
60−}
61−
62−void
63−supgen(Node *n)
64−{
65− long spc;
66− Prog *sp;
67−
68− if(n == Z)
69− return;
70− suppress++;
71− spc = pc;
72− sp = lastp;
73− gen(n);
74− lastp = sp;
75− pc = spc;
76− sp->link = nil;
77− suppress--;
78−}
79−
80−void
81−gen(Node *n)
82−{
83− Node *l, nod;
84− Prog *sp, *spc, *spb;
85− Case *cn;
86− long sbc, scc;
87− int o, f;
88−
89−loop:
90− if(n == Z)
91− return;
92− nearln = n->lineno;
93− o = n->op;
94− if(debug['G'])
95− if(o != OLIST)
96− print("%L %O\n", nearln, o);
97−
98− retok = 0;
99− switch(o) {
100−
101− default:
102− complex(n);
103− cgen(n, Z, 0);
104− break;
105−
106− case OLIST:
107− gen(n->left);
108−
109− rloop:
110− n = n->right;
111− goto loop;
112−
113− case ORETURN:
114− retok = 1;
115− complex(n);
116− if(n->type == T)
117− break;
118− l = n->left;
119− if(l == Z) {
120− noretval(3);
121− gbranch(ORETURN);
122− break;
123− }
124− if(typesuv[n->type->etype]) {
125− sugen(l, nodret, n->type->width);
126− noretval(3);
127− gbranch(ORETURN);
128− break;
129− }
130− regret(&nod, n);
131− cgen(l, &nod, 0);
132− regfree(&nod);
133− if(typefd[n->type->etype])
134− noretval(1);
135− else
136− noretval(2);
137− gbranch(ORETURN);
138− break;
139−
140− case OLABEL:
141− l = n->left;
142− if(l) {
143− l->pc = pc;
144− if(l->label)
145− patch(l->label, pc);
146− }
147− gbranch(OGOTO); /* prevent self reference in reg */
148− patch(p, pc);
149− goto rloop;
150−
151− case OGOTO:
152− retok = 1;
153− n = n->left;
154− if(n == Z)
155− return;
156− if(n->complex == 0) {
157− diag(Z, "label undefined: %s", n->sym->name);
158− return;
159− }
160− if(suppress)
161− return;
162− gbranch(OGOTO);
163− if(n->pc) {
164− patch(p, n->pc);
165− return;
166− }
167− if(n->label)
168− patch(n->label, pc-1);
169− n->label = p;
170− return;
171−
172− case OCASE:
173− l = n->left;
174− if(cases == C)
175− diag(n, "case/default outside a switch");
176− if(l == Z) {
177− casf();
178− cases->val = 0;
179− cases->def = 1;
180− cases->label = pc;
181− goto rloop;
182− }
183− complex(l);
184− if(l->type == T)
185− goto rloop;
186− if(l->op == OCONST)
187− if(typechl[l->type->etype]) {
188− casf();
189− cases->val = l->vconst;
190− cases->def = 0;
191− cases->label = pc;
192− goto rloop;
193− }
194− diag(n, "case expression must be integer constant");
195− goto rloop;
196−
197− case OSWITCH:
198− l = n->left;
199− complex(l);
200− if(l->type == T)
201− break;
202− if(!typechl[l->type->etype]) {
203− diag(n, "switch expression must be integer");
204− break;
205− }
206−
207− gbranch(OGOTO); /* entry */
208− sp = p;
209−
210− cn = cases;
211− cases = C;
212− casf();
213−
214− sbc = breakpc;
215− breakpc = pc;
216− gbranch(OGOTO);
217− spb = p;
218−
219− gen(n->right);
220− gbranch(OGOTO);
221− patch(p, breakpc);
222−
223− patch(sp, pc);
224− regalloc(&nod, l, Z);
225− nod.type = types[TLONG];
226− cgen(l, &nod, 0);
227− doswit(&nod);
228− regfree(&nod);
229− patch(spb, pc);
230−
231− cases = cn;
232− breakpc = sbc;
233− break;
234−
235− case OWHILE:
236− case ODWHILE:
237− l = n->left;
238− gbranch(OGOTO); /* entry */
239− sp = p;
240−
241− scc = continpc;
242− continpc = pc;
243− gbranch(OGOTO);
244− spc = p;
245−
246− sbc = breakpc;
247− breakpc = pc;
248− gbranch(OGOTO);
249− spb = p;
250−
251− patch(spc, pc);
252− if(n->op == OWHILE)
253− patch(sp, pc);
254− bcomplex(l, Z); /* test */
255− patch(p, breakpc);
256−
257− if(n->op == ODWHILE)
258− patch(sp, pc);
259− gen(n->right); /* body */
260− gbranch(OGOTO);
261− patch(p, continpc);
262−
263− patch(spb, pc);
264− continpc = scc;
265− breakpc = sbc;
266− break;
267−
268− case OFOR:
269− l = n->left;
270− gen(l->right->left); /* init */
271− gbranch(OGOTO); /* entry */
272− sp = p;
273−
274− scc = continpc;
275− continpc = pc;
276− gbranch(OGOTO);
277− spc = p;
278−
279− sbc = breakpc;
280− breakpc = pc;
281− gbranch(OGOTO);
282− spb = p;
283−
284− patch(spc, pc);
285− gen(l->right->right); /* inc */
286− patch(sp, pc);
287− if(l->left != Z) { /* test */
288− bcomplex(l->left, Z);
289− patch(p, breakpc);
290− }
291− gen(n->right); /* body */
292− gbranch(OGOTO);
293− patch(p, continpc);
294−
295− patch(spb, pc);
296− continpc = scc;
297− breakpc = sbc;
298− break;
299−
300− case OCONTINUE:
301− if(continpc < 0) {
302− diag(n, "continue not in a loop");
303− break;
304− }
305− gbranch(OGOTO);
306− patch(p, continpc);
307− break;
308−
309− case OBREAK:
310− if(breakpc < 0) {
311− diag(n, "break not in a loop");
312− break;
313− }
314− gbranch(OGOTO);
315− patch(p, breakpc);
316− break;
317−
318− case OIF:
319− l = n->left;
320− if(bcomplex(l, n->right)) {
321− if(typefd[l->type->etype])
322− f = !l->fconst;
323− else
324− f = !l->vconst;
325− if(debug['c'])
326− print("%L const if %s\n", nearln, f ? "false" : "true");
327− if(f) {
328− supgen(n->right->left);
329− gen(n->right->right);
330− }
331− else {
332− gen(n->right->left);
333− supgen(n->right->right);
334− }
335− }
336− else {
337− sp = p;
338− if(n->right->left != Z)
339− gen(n->right->left);
340− if(n->right->right != Z) {
341− gbranch(OGOTO);
342− patch(sp, pc);
343− sp = p;
344− gen(n->right->right);
345− }
346− patch(sp, pc);
347− }
348− break;
349−
350− case OSET:
351− case OUSED:
352− usedset(n->left, o);
353− break;
354− }
355−}
356−
357−void
358−usedset(Node *n, int o)
359−{
360− if(n->op == OLIST) {
361− usedset(n->left, o);
362− usedset(n->right, o);
363− return;
364− }
365− complex(n);
366− switch(n->op) {
367− case OADDR: /* volatile */
368− gins(ANOP, n, Z);
369− break;
370− case ONAME:
371− if(o == OSET)
372− gins(ANOP, Z, n);
373− else
374− gins(ANOP, n, Z);
375− break;
376− }
377−}
378−
3793 void
3804 noretval(int n)
3815 {
@@ -593,21 +217,3 @@ xcom(Node *n) · 211 unmodified lines
593217 break;
594218 }
595219 }
596−
597−int
598−bcomplex(Node *n, Node *c)
599−{
600−
601− complex(n);
602− if(n->type != T)
603− if(tcompat(n, T, n->type, tnot))
604− n->type = T;
605− if(n->type != T) {
606− if(c != Z && n->op == OCONST && deadheads(c))
607− return 1;
608− bool64(n);
609− boolgen(n, 1, Z);
610− } else
611− gbranch(OGOTO);
612− return 0;
613−}
utils/5c/swt.c+8−129
@@ -1,62 +1,17 @@
11 #include "gc.h"
22
3−int
4−swcmp(const void *a1, const void *a2)
5−{
6− C1 *p1, *p2;
7−
8− p1 = (C1*)a1;
9− p2 = (C1*)a2;
10− if(p1->val < p2->val)
11− return -1;
12− return p1->val > p2->val;
13−}
14−
153 void
16−doswit(Node *n)
4+swit1(C1 *q, int nc, long def, Node *n)
175 {
18− Case *c;
19− C1 *q, *iq;
20− long def, nc, i;
216 Node tn;
22−
23− def = 0;
24− nc = 0;
25− for(c = cases; c->link != C; c = c->link) {
26− if(c->def) {
27− if(def)
28− diag(n, "more than one default in switch");
29− def = c->label;
30− continue;
31− }
32− nc++;
33− }
34−
35− iq = alloc(nc*sizeof(C1));
36− q = iq;
37− for(c = cases; c->link != C; c = c->link) {
38− if(c->def)
39− continue;
40− q->label = c->label;
41− q->val = c->val;
42− q++;
43− }
44− qsort(iq, nc, sizeof(C1), swcmp);
45− if(debug['W'])
46− for(i=0; i<nc; i++)
47− print("case %2ld: = %.8lux\n", i, iq[i].val);
48− if(def == 0)
49− def = breakpc;
50− for(i=0; i<nc-1; i++)
51− if(iq[i].val == iq[i+1].val)
52− diag(n, "duplicate cases in switch %ld", iq[i].val);
7+
538 regalloc(&tn, &regnode, Z);
54− swit1(iq, nc, def, n, &tn);
9+ swit2(q, nc, def, n, &tn);
5510 regfree(&tn);
5611 }
5712
5813 void
59−swit1(C1 *q, int nc, long def, Node *n, Node *tn)
14+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
6015 {
6116 C1 *r;
6217 int i;
@@ -89,12 +44,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 26 unmodified lines
8944 sp = p;
9045 gopcode(OEQ, nodconst(r->val), n, Z); /* just gen the B.EQ */
9146 patch(p, r->label);
92− swit1(q, i, def, n, tn);
47+ swit2(q, i, def, n, tn);
9348
9449 if(debug['W'])
9550 print("case < %.8lux\n", r->val);
9651 patch(sp, pc);
97− swit1(r+1, nc-i-1, def, n, tn);
52+ swit2(r+1, nc-i-1, def, n, tn);
9853 return;
9954
10055 direct:
@@ -122,16 +77,6 @@ direct: · 21 unmodified lines
12277 patch(p, def);
12378 }
12479
125−void
126−casf(void)
127−{
128− Case *c;
129−
130− c = alloc(sizeof(*c));
131− c->link = cases;
132− cases = c;
133−}
134−
13580 void
13681 bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
13782 {
@@ -153,7 +98,7 @@ bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn) · 15 unmodified lines
15398 gopcode(OAS, n3, Z, n1);
15499 } else {
155100 regalloc(n1, l, nn);
156− cgen(l, n1, 0);
101+ cgen(l, n1);
157102 }
158103 if(b->type->shift == 0 && typeu[b->type->etype]) {
159104 v = ~0 + (1L << b->type->nbits);
@@ -229,33 +174,6 @@ outstring(char *s, long n) · 69 unmodified lines
229174 return r;
230175 }
231176
232−long
233−outlstring(ushort *s, long n)
234−{
235− char buf[2];
236− int c;
237− long r;
238−
239− if(suppress)
240− return nstring;
241− while(nstring & 1)
242− outstring("", 1);
243− r = nstring;
244− while(n > 0) {
245− c = *s++;
246− if(align(0, types[TCHAR], Aarg1)) {
247− buf[0] = c>>8;
248− buf[1] = c;
249− } else {
250− buf[0] = c;
251− buf[1] = c>>8;
252− }
253− outstring(buf, 2);
254− n -= sizeof(ushort);
255− }
256− return r;
257−}
258−
259177 int
260178 mulcon(Node *n, Node *nn)
261179 {
@@ -297,7 +215,7 @@ mulcon(Node *n, Node *nn) · 35 unmodified lines
297215 if(p[1] == 'i')
298216 p += 2;
299217 regalloc(&nod1, n, nn);
300− cgen(l, &nod1, 0);
218+ cgen(l, &nod1);
301219 vs = v;
302220 regalloc(&nod2, n, Z);
303221
@@ -350,16 +268,6 @@ loop: · 46 unmodified lines
350268 goto loop;
351269 }
352270
353−void
354−nullwarn(Node *l, Node *r)
355−{
356− warn(Z, "result of operation not used");
357− if(l != Z)
358− cgen(l, Z, 0);
359− if(r != Z)
360− cgen(r, Z, 0);
361−}
362−
363271 void
364272 sextern(Sym *s, Node *a, long o, long w)
365273 {
@@ -651,35 +559,6 @@ zaddr(char *bp, Adr *a, int s) · 285 unmodified lines
651559 return bp;
652560 }
653561
654−void
655−ieeedtod(Ieee *ieee, double native)
656−{
657− double fr, ho, f;
658− int exp;
659−
660− if(native < 0) {
661− ieeedtod(ieee, -native);
662− ieee->h |= 0x80000000L;
663− return;
664− }
665− if(native == 0) {
666− ieee->l = 0;
667− ieee->h = 0;
668− return;
669− }
670− fr = frexp(native, &exp);
671− f = 2097152L; /* shouldnt use fp constants here */
672− fr = modf(fr*f, &ho);
673− ieee->h = ho;
674− ieee->h &= 0xfffffL;
675− ieee->h |= (exp+1022L) << 20;
676− f = 65536L;
677− fr = modf(fr*f, &ho);
678− ieee->l = ho;
679− ieee->l <<= 16;
680− ieee->l |= (long)(fr*f);
681−}
682−
683562 long
684563 align(long i, Type *t, int op)
685564 {
utils/5c/txt.c+5−5
@@ -170,7 +170,7 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) · 169 unmodified lines
170170 nod.left = *fnxp;
171171 nod.right = n;
172172 nod.type = n->type;
173− cgen(&nod, Z, 0);
173+ cgen(&nod, Z);
174174 (*fnxp)++;
175175 }
176176 return;
@@ -187,18 +187,18 @@ garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) · 10 unmodified lines
187187 if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
188188 regaalloc1(tn1, n);
189189 if(n->complex >= FNX) {
190− cgen(*fnxp, tn1, 0);
190+ cgen(*fnxp, tn1);
191191 (*fnxp)++;
192192 } else
193− cgen(n, tn1, 0);
193+ cgen(n, tn1);
194194 return;
195195 }
196196 regalloc(tn1, n, Z);
197197 if(n->complex >= FNX) {
198− cgen(*fnxp, tn1, 0);
198+ cgen(*fnxp, tn1);
199199 (*fnxp)++;
200200 } else
201− cgen(n, tn1, 0);
201+ cgen(n, tn1);
202202 regaalloc(tn2, n);
203203 gopcode(OAS, tn1, Z, tn2);
204204 regfree(tn1);
utils/kc/gc.h+6−3
@@ -57,6 +57,7 @@ struct Case · 56 unmodified lines
5757 long val;
5858 long label;
5959 char def;
60+ char isv;
6061 };
6162 #define C ((Case*)0)
6263
@@ -128,6 +129,7 @@ struct Rgn · 65 unmodified lines
128129 };
129130
130131 EXTERN long breakpc;
132+EXTERN long nbreak;
131133 EXTERN Case* cases;
132134 EXTERN Node constnode;
133135 EXTERN Node fconstnode;
@@ -140,7 +142,6 @@ EXTERN int hintabsize; · 6 unmodified lines
140142 EXTERN long maxargsafe;
141143 EXTERN Multab multab[20];
142144 EXTERN int mnstring;
143−EXTERN int retok;
144145 EXTERN Node* nodrat;
145146 EXTERN Node* nodret;
146147 EXTERN Node* nodsafe;
@@ -183,6 +184,7 @@ EXTERN long regbits; · 36 unmodified lines
183184 EXTERN long exregbits;
184185
185186 EXTERN int change;
187+EXTERN int suppress;
186188
187189 EXTERN Reg* firstr;
188190 EXTERN Reg* lastr;
@@ -204,7 +206,7 @@ void gen(Node*); · 15 unmodified lines
204206 void usedset(Node*, int);
205207 void noretval(int);
206208 void xcom(Node*);
207−void bcomplex(Node*);
209+int bcomplex(Node*, Node*);
208210
209211 /*
210212 * cgen.c
@@ -255,7 +257,8 @@ void gpseudo(int, Sym*, Node*); · 44 unmodified lines
255257 */
256258 int swcmp(const void*, const void*);
257259 void doswit(Node*);
258−void swit1(C1*, int, long, Node*, Node*);
260+void swit1(C1*, int, long, Node*);
261+void swit2(C1*, int, long, Node*, Node*);
259262 void casf(void);
260263 void bitload(Node*, Node*, Node*, Node*, Node*);
261264 void bitstore(Node*, Node*, Node*, Node*, Node*);
utils/kc/mkfile+8−0
@@ -4,6 +4,8 @@ TARG=kc · 3 unmodified lines
44
55 OFILES=\
66 peep.$O\
7+ pgen.$O\
8+ pswt.$O\
79 reg.$O\
810 cgen.$O\
911 enam.$O\
@@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 20 unmodified lines
3032 cd ../cc
3133 mk $MKFLAGS install
3234 mk $MKFLAGS clean
35+
36+%.$O: ../cc/%.c
37+ $CC $CFLAGS -I. ../cc/$stem.c
38+
39+#enam.c: k.out.h
40+# rc mkenam
utils/kc/sgen.c+0−352
@@ -1,343 +1,5 @@
11 #include "gc.h"
22
3−void
4−codgen(Node *n, Node *nn)
5−{
6− Prog *sp;
7− Node *n1, nod, nod1;
8−
9− cursafe = 0;
10− curarg = 0;
11− maxargsafe = 0;
12−
13− /*
14− * isolate name
15− */
16− for(n1 = nn;; n1 = n1->left) {
17− if(n1 == Z) {
18− diag(nn, "cant find function name");
19− return;
20− }
21− if(n1->op == ONAME)
22− break;
23− }
24− nearln = nn->lineno;
25− gpseudo(ATEXT, n1->sym, nodconst(stkoff));
26− sp = p;
27−
28− /*
29− * isolate first argument
30− */
31− if(REGARG) {
32− if(typesuv[thisfn->link->etype]) {
33− nod1 = *nodret->left;
34− nodreg(&nod, &nod1, REGARG);
35− gopcode(OAS, &nod, Z, &nod1);
36− } else
37− if(firstarg && typechlp[firstargtype->etype]) {
38− nod1 = *nodret->left;
39− nod1.sym = firstarg;
40− nod1.type = firstargtype;
41− nod1.xoffset = align(0, firstargtype, Aarg1);
42− nod1.etype = firstargtype->etype;
43− nodreg(&nod, &nod1, REGARG);
44− gopcode(OAS, &nod, Z, &nod1);
45− }
46− }
47−
48− retok = 0;
49− gen(n);
50− if(!retok)
51− if(thisfn->link->etype != TVOID)
52− warn(Z, "no return at end of function: %s", n1->sym->name);
53− noretval(3);
54− gbranch(ORETURN);
55−
56− if(!debug['N'] || debug['R'] || debug['P'])
57− regopt(sp);
58−
59− sp->to.offset += maxargsafe;
60−}
61−
62−void
63−gen(Node *n)
64−{
65− Node *l, nod;
66− Prog *sp, *spc, *spb;
67− Case *cn;
68− long sbc, scc;
69− int o;
70−
71−loop:
72− if(n == Z)
73− return;
74− nearln = n->lineno;
75− o = n->op;
76− if(debug['G'])
77− if(o != OLIST)
78− print("%L %O\n", nearln, o);
79− retok = 0;
80− switch(o) {
81−
82− default:
83− complex(n);
84− cgen(n, Z);
85− break;
86−
87− case OLIST:
88− gen(n->left);
89−
90− rloop:
91− n = n->right;
92− goto loop;
93−
94− case ORETURN:
95− retok = 1;
96− complex(n);
97− if(n->type == T)
98− break;
99− l = n->left;
100− if(l == Z) {
101− noretval(3);
102− gbranch(ORETURN);
103− break;
104− }
105− if(typesuv[n->type->etype]) {
106− sugen(l, nodret, n->type->width);
107− noretval(3);
108− gbranch(ORETURN);
109− break;
110− }
111− regret(&nod, n);
112− cgen(l, &nod);
113− regfree(&nod);
114− if(typefd[n->type->etype])
115− noretval(1);
116− else
117− noretval(2);
118− gbranch(ORETURN);
119− break;
120−
121− case OLABEL:
122− l = n->left;
123− if(l) {
124− l->xoffset = pc;
125− if(l->label)
126− patch(l->label, pc);
127− }
128− gbranch(OGOTO); /* prevent self reference in reg */
129− patch(p, pc);
130− goto rloop;
131−
132− case OGOTO:
133− retok = 1;
134− n = n->left;
135− if(n == Z)
136− return;
137− if(n->complex == 0) {
138− diag(Z, "label undefined: %s", n->sym->name);
139− return;
140− }
141− gbranch(OGOTO);
142− if(n->xoffset) {
143− patch(p, n->xoffset);
144− return;
145− }
146− if(n->label)
147− patch(n->label, pc-1);
148− n->label = p;
149− return;
150−
151− case OCASE:
152− l = n->left;
153− if(cases == C)
154− diag(n, "case/default outside a switch");
155− if(l == Z) {
156− casf();
157− cases->val = 0;
158− cases->def = 1;
159− cases->label = pc;
160− goto rloop;
161− }
162− complex(l);
163− if(l->type == T)
164− goto rloop;
165− if(l->op == OCONST)
166− if(typechl[l->type->etype]) {
167− casf();
168− cases->val = l->vconst;
169− cases->def = 0;
170− cases->label = pc;
171− goto rloop;
172− }
173− diag(n, "case expression must be integer constant");
174− goto rloop;
175−
176− case OSWITCH:
177− l = n->left;
178− complex(l);
179− if(l->type == T)
180− break;
181− if(!typechl[l->type->etype]) {
182− diag(n, "switch expression must be integer");
183− break;
184− }
185−
186− gbranch(OGOTO); /* entry */
187− sp = p;
188−
189− cn = cases;
190− cases = C;
191− casf();
192−
193− sbc = breakpc;
194− breakpc = pc;
195− gbranch(OGOTO);
196− spb = p;
197−
198− gen(n->right);
199− gbranch(OGOTO);
200− patch(p, breakpc);
201−
202− patch(sp, pc);
203− regalloc(&nod, l, Z);
204− nod.type = types[TLONG];
205− cgen(l, &nod);
206− doswit(&nod);
207− regfree(&nod);
208− patch(spb, pc);
209−
210− cases = cn;
211− breakpc = sbc;
212− break;
213−
214− case OWHILE:
215− case ODWHILE:
216− l = n->left;
217− gbranch(OGOTO); /* entry */
218− sp = p;
219−
220− scc = continpc;
221− continpc = pc;
222− gbranch(OGOTO);
223− spc = p;
224−
225− sbc = breakpc;
226− breakpc = pc;
227− gbranch(OGOTO);
228− spb = p;
229−
230− patch(spc, pc);
231− if(n->op == OWHILE)
232− patch(sp, pc);
233− bcomplex(l); /* test */
234− patch(p, breakpc);
235−
236− if(n->op == ODWHILE)
237− patch(sp, pc);
238− gen(n->right); /* body */
239− gbranch(OGOTO);
240− patch(p, continpc);
241−
242− patch(spb, pc);
243− continpc = scc;
244− breakpc = sbc;
245− break;
246−
247− case OFOR:
248− l = n->left;
249− gen(l->right->left); /* init */
250− gbranch(OGOTO); /* entry */
251− sp = p;
252−
253− scc = continpc;
254− continpc = pc;
255− gbranch(OGOTO);
256− spc = p;
257−
258− sbc = breakpc;
259− breakpc = pc;
260− gbranch(OGOTO);
261− spb = p;
262−
263− patch(spc, pc);
264− gen(l->right->right); /* inc */
265− patch(sp, pc);
266− if(l->left != Z) { /* test */
267− bcomplex(l->left);
268− patch(p, breakpc);
269− }
270− gen(n->right); /* body */
271− gbranch(OGOTO);
272− patch(p, continpc);
273−
274− patch(spb, pc);
275− continpc = scc;
276− breakpc = sbc;
277− break;
278−
279− case OCONTINUE:
280− if(continpc < 0) {
281− diag(n, "continue not in a loop");
282− break;
283− }
284− gbranch(OGOTO);
285− patch(p, continpc);
286− break;
287−
288− case OBREAK:
289− if(breakpc < 0) {
290− diag(n, "break not in a loop");
291− break;
292− }
293− gbranch(OGOTO);
294− patch(p, breakpc);
295− break;
296−
297− case OIF:
298− l = n->left;
299− bcomplex(l);
300− sp = p;
301− if(n->right->left != Z)
302− gen(n->right->left);
303− if(n->right->right != Z) {
304− gbranch(OGOTO);
305− patch(sp, pc);
306− sp = p;
307− gen(n->right->right);
308− }
309− patch(sp, pc);
310− break;
311−
312− case OSET:
313− case OUSED:
314− usedset(n->left, o);
315− break;
316− }
317−}
318−
319−void
320−usedset(Node *n, int o)
321−{
322− if(n->op == OLIST) {
323− usedset(n->left, o);
324− usedset(n->right, o);
325− return;
326− }
327− complex(n);
328− switch(n->op) {
329− case OADDR: /* volatile */
330− gins(ANOP, n, Z);
331− break;
332− case ONAME:
333− if(o == OSET)
334− gins(ANOP, Z, n);
335− else
336− gins(ANOP, n, Z);
337− break;
338− }
339−}
340−
3413 void
3424 noretval(int n)
3435 {
@@ -574,17 +236,3 @@ xcom(Node *n) · 230 unmodified lines
574236 }
575237 }
576238
577−void
578−bcomplex(Node *n)
579−{
580−
581− complex(n);
582− if(n->type != T)
583− if(tcompat(n, T, n->type, tnot))
584− n->type = T;
585− if(n->type != T) {
586− bool64(n);
587− boolgen(n, 1, Z);
588− } else
589− gbranch(OGOTO);
590−}
utils/kc/swt.c+6−122
@@ -1,59 +1,17 @@
11 #include "gc.h"
22
3−int
4−swcmp(const void *a1, const void *a2)
5−{
6− C1 *p1, *p2;
7−
8− p1 = (C1*)a1;
9− p2 = (C1*)a2;
10− if(p1->val < p2->val)
11− return -1;
12− return p1->val > p2->val;
13−}
14−
153 void
16−doswit(Node *n)
4+swit1(C1 *q, int nc, long def, Node *n)
175 {
18− Case *c;
19− C1 *q, *iq;
20− long def, nc, i;
216 Node tn;
22−
23− def = 0;
24− nc = 0;
25− for(c = cases; c->link != C; c = c->link) {
26− if(c->def) {
27− if(def)
28− diag(n, "more than one default in switch");
29− def = c->label;
30− continue;
31− }
32− nc++;
33− }
34−
35− iq = alloc(nc*sizeof(C1));
36− q = iq;
37− for(c = cases; c->link != C; c = c->link) {
38− if(c->def)
39− continue;
40− q->label = c->label;
41− q->val = c->val;
42− q++;
43− }
44− qsort(iq, nc, sizeof(C1), swcmp);
45− if(def == 0)
46− def = breakpc;
47− for(i=0; i<nc-1; i++)
48− if(iq[i].val == iq[i+1].val)
49− diag(n, "duplicate cases in switch %ld", iq[i].val);
7+
508 regalloc(&tn, &regnode, Z);
51− swit1(iq, nc, def, n, &tn);
9+ swit2(q, nc, def, n, &tn);
5210 regfree(&tn);
5311 }
5412
5513 void
56−swit1(C1 *q, int nc, long def, Node *n, Node *tn)
14+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
5715 {
5816 C1 *r;
5917 int i;
@@ -87,20 +45,10 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 27 unmodified lines
8745 gbranch(OGOTO);
8846 p->as = ABE;
8947 patch(p, r->label);
90− swit1(q, i, def, n, tn);
48+ swit2(q, i, def, n, tn);
9149
9250 patch(sp, pc);
93− swit1(r+1, nc-i-1, def, n, tn);
94−}
95−
96−void
97−casf(void)
98−{
99− Case *c;
100−
101− c = alloc(sizeof(*c));
102− c->link = cases;
103− cases = c;
51+ swit2(r+1, nc-i-1, def, n, tn);
10452 }
10553
10654 void
@@ -198,31 +146,6 @@ outstring(char *s, long n) · 91 unmodified lines
198146 return r;
199147 }
200148
201−long
202−outlstring(ushort *s, long n)
203−{
204− char buf[2];
205− int c;
206− long r;
207−
208− while(nstring & 1)
209− outstring("", 1);
210− r = nstring;
211− while(n > 0) {
212− c = *s++;
213− if(align(0, types[TCHAR], Aarg1)) {
214− buf[0] = c>>8;
215− buf[1] = c;
216− } else {
217− buf[0] = c;
218− buf[1] = c>>8;
219− }
220− outstring(buf, 2);
221− n -= sizeof(ushort);
222− }
223− return r;
224−}
225−
226149 int
227150 mulcon(Node *n, Node *nn)
228151 {
@@ -312,16 +235,6 @@ loop: · 83 unmodified lines
312235 goto loop;
313236 }
314237
315−void
316−nullwarn(Node *l, Node *r)
317−{
318− warn(Z, "result of operation not used");
319− if(l != Z)
320− cgen(l, Z);
321− if(r != Z)
322− cgen(r, Z);
323−}
324−
325238 void
326239 sextern(Sym *s, Node *a, long o, long w)
327240 {
@@ -609,35 +522,6 @@ zaddr(Biobuf *b, Adr *a, int s) · 281 unmodified lines
609522 }
610523 }
611524
612−void
613−ieeedtod(Ieee *ieee, double native)
614−{
615− double fr, ho, f;
616− int exp;
617−
618− if(native < 0) {
619− ieeedtod(ieee, -native);
620− ieee->h |= 0x80000000L;
621− return;
622− }
623− if(native == 0) {
624− ieee->l = 0;
625− ieee->h = 0;
626− return;
627− }
628− fr = frexp(native, &exp);
629− f = 2097152L; /* shouldnt use fp constants here */
630− fr = modf(fr*f, &ho);
631− ieee->h = ho;
632− ieee->h &= 0xfffffL;
633− ieee->h |= (exp+1022L) << 20;
634− f = 65536L;
635− fr = modf(fr*f, &ho);
636− ieee->l = ho;
637− ieee->l <<= 16;
638− ieee->l |= (long)(fr*f);
639−}
640−
641525 long
642526 align(long i, Type *t, int op)
643527 {
utils/vc/cgen.c+2−0
@@ -497,6 +497,8 @@ cgen(Node *n, Node *nn) · 496 unmodified lines
497497 } else
498498 gopcode(OADD, nodconst(v), Z, &nod);
499499 gopcode(OAS, &nod, Z, &nod2);
500+ if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
501+ gins(ANOP, l, Z);
500502
501503 regfree(&nod);
502504 if(l->addable < INDEXED)
utils/vc/gc.h+6−3
@@ -58,6 +58,7 @@ struct Case · 57 unmodified lines
5858 long val;
5959 long label;
6060 char def;
61+ char isv;
6162 };
6263 #define C ((Case*)0)
6364
@@ -129,6 +130,7 @@ struct Rgn · 65 unmodified lines
129130 };
130131
131132 EXTERN long breakpc;
133+EXTERN long nbreak;
132134 EXTERN Case* cases;
133135 EXTERN Node constnode;
134136 EXTERN Node fconstnode;
@@ -140,7 +142,6 @@ EXTERN Prog* lastp; · 5 unmodified lines
140142 EXTERN long maxargsafe;
141143 EXTERN int mnstring;
142144 EXTERN Multab multab[20];
143−EXTERN int retok;
144145 EXTERN int hintabsize;
145146 EXTERN Node* nodrat;
146147 EXTERN Node* nodret;
@@ -184,6 +185,7 @@ EXTERN long regbits; · 37 unmodified lines
184185 EXTERN long exregbits;
185186
186187 EXTERN int change;
188+EXTERN int suppress;
187189
188190 EXTERN Reg* firstr;
189191 EXTERN Reg* lastr;
@@ -204,7 +206,7 @@ void codgen(Node*, Node*); · 14 unmodified lines
204206 void gen(Node*);
205207 void noretval(int);
206208 void xcom(Node*);
207−void bcomplex(Node*);
209+int bcomplex(Node*, Node*);
208210 void usedset(Node*, int);
209211
210212 /*
@@ -256,7 +258,8 @@ void gpseudo(int, Sym*, Node*); · 45 unmodified lines
256258 */
257259 int swcmp(const void*, const void*);
258260 void doswit(Node*);
259−void swit1(C1*, int, long, Node*, Node*);
261+void swit1(C1*, int, long, Node*);
262+void swit2(C1*, int, long, Node*, Node*);
260263 void casf(void);
261264 void bitload(Node*, Node*, Node*, Node*, Node*);
262265 void bitstore(Node*, Node*, Node*, Node*, Node*);
utils/vc/mkfile+8−0
@@ -7,6 +7,8 @@ OFILES=\ · 6 unmodified lines
77 enam.$O\
88 list.$O\
99 peep.$O\
10+ pgen.$O\
11+ pswt.$O\
1012 reg.$O\
1113 sgen.$O\
1214 swt.$O\
@@ -30,3 +32,9 @@ $ROOT/$OBJDIR/lib/libcc.a: · 17 unmodified lines
3032 cd ../cc
3133 mk $MKFLAGS install
3234 mk $MKFLAGS clean
35+
36+%.$O: ../cc/%.c
37+ $CC $CFLAGS -I. ../cc/$stem.c
38+
39+#enam.c: v.out.h
40+# rc mkenam
utils/vc/peep.c+1−1
@@ -569,7 +569,7 @@ copyu(Prog *p, Adr *v, Adr *s) · 568 unmodified lines
569569 return 3;
570570 return 0;
571571 }
572− return 0;
572+ /* not reached */
573573 }
574574
575575 int
utils/vc/sgen.c+0−353
@@ -1,344 +1,5 @@
11 #include "gc.h"
22
3−void
4−codgen(Node *n, Node *nn)
5−{
6− Prog *sp;
7− Node *n1, nod, nod1;
8−
9− cursafe = 0;
10− curarg = 0;
11− maxargsafe = 0;
12−
13− /*
14− * isolate name
15− */
16− for(n1 = nn;; n1 = n1->left) {
17− if(n1 == Z) {
18− diag(nn, "cant find function name");
19− return;
20− }
21− if(n1->op == ONAME)
22− break;
23− }
24− nearln = nn->lineno;
25− gpseudo(ATEXT, n1->sym, nodconst(stkoff));
26− sp = p;
27−
28− /*
29− * isolate first argument
30− */
31− if(REGARG) {
32− if(typesuv[thisfn->link->etype]) {
33− nod1 = *nodret->left;
34− nodreg(&nod, &nod1, REGARG);
35− gopcode(OAS, &nod, Z, &nod1);
36− } else
37− if(firstarg && typechlp[firstargtype->etype]) {
38− nod1 = *nodret->left;
39− nod1.sym = firstarg;
40− nod1.type = firstargtype;
41− nod1.xoffset = align(0, firstargtype, Aarg1);
42− nod1.etype = firstargtype->etype;
43− nodreg(&nod, &nod1, REGARG);
44− gopcode(OAS, &nod, Z, &nod1);
45− }
46− }
47−
48− retok = 0;
49− gen(n);
50− if(!retok)
51− if(thisfn->link->etype != TVOID)
52− warn(Z, "no return at end of function: %s", n1->sym->name);
53− noretval(3);
54− gbranch(ORETURN);
55−
56− if(!debug['N'] || debug['R'] || debug['P'])
57− regopt(sp);
58−
59− sp->to.offset += maxargsafe;
60−}
61−
62−void
63−gen(Node *n)
64−{
65− Node *l, nod;
66− Prog *sp, *spc, *spb;
67− Case *cn;
68− long sbc, scc;
69− int o;
70−
71−loop:
72− if(n == Z)
73− return;
74− nearln = n->lineno;
75− o = n->op;
76− if(debug['G'])
77− if(o != OLIST)
78− print("%L %O\n", nearln, o);
79−
80− retok = 0;
81− switch(o) {
82−
83− default:
84− complex(n);
85− cgen(n, Z);
86− break;
87−
88− case OLIST:
89− gen(n->left);
90−
91− rloop:
92− n = n->right;
93− goto loop;
94−
95− case ORETURN:
96− retok = 1;
97− complex(n);
98− if(n->type == T)
99− break;
100− l = n->left;
101− if(l == Z) {
102− noretval(3);
103− gbranch(ORETURN);
104− break;
105− }
106− if(typesuv[n->type->etype]) {
107− sugen(l, nodret, n->type->width);
108− noretval(3);
109− gbranch(ORETURN);
110− break;
111− }
112− regret(&nod, n);
113− cgen(l, &nod);
114− regfree(&nod);
115− if(typefd[n->type->etype])
116− noretval(1);
117− else
118− noretval(2);
119− gbranch(ORETURN);
120− break;
121−
122− case OLABEL:
123− l = n->left;
124− if(l) {
125− l->pc = pc;
126− if(l->label)
127− patch(l->label, pc);
128− }
129− gbranch(OGOTO); /* prevent self reference in reg */
130− patch(p, pc);
131− goto rloop;
132−
133− case OGOTO:
134− retok = 1;
135− n = n->left;
136− if(n == Z)
137− return;
138− if(n->complex == 0) {
139− diag(Z, "label undefined: %s", n->sym->name);
140− return;
141− }
142− gbranch(OGOTO);
143− if(n->pc) {
144− patch(p, n->pc);
145− return;
146− }
147− if(n->label)
148− patch(n->label, pc-1);
149− n->label = p;
150− return;
151−
152− case OCASE:
153− l = n->left;
154− if(cases == C)
155− diag(n, "case/default outside a switch");
156− if(l == Z) {
157− casf();
158− cases->val = 0;
159− cases->def = 1;
160− cases->label = pc;
161− goto rloop;
162− }
163− complex(l);
164− if(l->type == T)
165− goto rloop;
166− if(l->op == OCONST)
167− if(typechl[l->type->etype]) {
168− casf();
169− cases->val = l->vconst;
170− cases->def = 0;
171− cases->label = pc;
172− goto rloop;
173− }
174− diag(n, "case expression must be integer constant");
175− goto rloop;
176−
177− case OSWITCH:
178− l = n->left;
179− complex(l);
180− if(l->type == T)
181− break;
182− if(!typechl[l->type->etype]) {
183− diag(n, "switch expression must be integer");
184− break;
185− }
186−
187− gbranch(OGOTO); /* entry */
188− sp = p;
189−
190− cn = cases;
191− cases = C;
192− casf();
193−
194− sbc = breakpc;
195− breakpc = pc;
196− gbranch(OGOTO);
197− spb = p;
198−
199− gen(n->right);
200− gbranch(OGOTO);
201− patch(p, breakpc);
202−
203− patch(sp, pc);
204− regalloc(&nod, l, Z);
205− nod.type = types[TLONG];
206− cgen(l, &nod);
207− doswit(&nod);
208− regfree(&nod);
209− patch(spb, pc);
210−
211− cases = cn;
212− breakpc = sbc;
213− break;
214−
215− case OWHILE:
216− case ODWHILE:
217− l = n->left;
218− gbranch(OGOTO); /* entry */
219− sp = p;
220−
221− scc = continpc;
222− continpc = pc;
223− gbranch(OGOTO);
224− spc = p;
225−
226− sbc = breakpc;
227− breakpc = pc;
228− gbranch(OGOTO);
229− spb = p;
230−
231− patch(spc, pc);
232− if(n->op == OWHILE)
233− patch(sp, pc);
234− bcomplex(l); /* test */
235− patch(p, breakpc);
236−
237− if(n->op == ODWHILE)
238− patch(sp, pc);
239− gen(n->right); /* body */
240− gbranch(OGOTO);
241− patch(p, continpc);
242−
243− patch(spb, pc);
244− continpc = scc;
245− breakpc = sbc;
246− break;
247−
248− case OFOR:
249− l = n->left;
250− gen(l->right->left); /* init */
251− gbranch(OGOTO); /* entry */
252− sp = p;
253−
254− scc = continpc;
255− continpc = pc;
256− gbranch(OGOTO);
257− spc = p;
258−
259− sbc = breakpc;
260− breakpc = pc;
261− gbranch(OGOTO);
262− spb = p;
263−
264− patch(spc, pc);
265− gen(l->right->right); /* inc */
266− patch(sp, pc);
267− if(l->left != Z) { /* test */
268− bcomplex(l->left);
269− patch(p, breakpc);
270− }
271− gen(n->right); /* body */
272− gbranch(OGOTO);
273− patch(p, continpc);
274−
275− patch(spb, pc);
276− continpc = scc;
277− breakpc = sbc;
278− break;
279−
280− case OCONTINUE:
281− if(continpc < 0) {
282− diag(n, "continue not in a loop");
283− break;
284− }
285− gbranch(OGOTO);
286− patch(p, continpc);
287− break;
288−
289− case OBREAK:
290− if(breakpc < 0) {
291− diag(n, "break not in a loop");
292− break;
293− }
294− gbranch(OGOTO);
295− patch(p, breakpc);
296− break;
297−
298− case OIF:
299− l = n->left;
300− bcomplex(l);
301− sp = p;
302− if(n->right->left != Z)
303− gen(n->right->left);
304− if(n->right->right != Z) {
305− gbranch(OGOTO);
306− patch(sp, pc);
307− sp = p;
308− gen(n->right->right);
309− }
310− patch(sp, pc);
311− break;
312−
313− case OSET:
314− case OUSED:
315− usedset(n->left, o);
316− break;
317− }
318−}
319−
320−void
321−usedset(Node *n, int o)
322−{
323− if(n->op == OLIST) {
324− usedset(n->left, o);
325− usedset(n->right, o);
326− return;
327− }
328− complex(n);
329− switch(n->op) {
330− case OADDR: /* volatile */
331− gins(ANOP, n, Z);
332− break;
333− case ONAME:
334− if(o == OSET)
335− gins(ANOP, Z, n);
336− else
337− gins(ANOP, n, Z);
338− break;
339− }
340−}
341−
3423 void
3434 noretval(int n)
3445 {
@@ -564,17 +225,3 @@ xcom(Node *n) · 219 unmodified lines
564225 }
565226 }
566227
567−void
568−bcomplex(Node *n)
569−{
570−
571− complex(n);
572− if(n->type != T)
573− if(tcompat(n, T, n->type, tnot))
574− n->type = T;
575− if(n->type != T) {
576− bool64(n);
577− boolgen(n, 1, Z);
578− } else
579− gbranch(OGOTO);
580−}
utils/vc/swt.c+12−126
@@ -1,62 +1,17 @@
11 #include "gc.h"
22
3−int
4−swcmp(const void *a1, const void *a2)
5−{
6− C1 *p1, *p2;
7−
8− p1 = (C1*)a1;
9− p2 = (C1*)a2;
10− if(p1->val < p2->val)
11− return -1;
12− return p1->val > p2->val;
13−}
14−
153 void
16−doswit(Node *n)
4+swit1(C1 *q, int nc, long def, Node *n)
175 {
18− Case *c;
19− C1 *q, *iq;
20− long def, nc, i;
216 Node tn;
22−
23− def = 0;
24− nc = 0;
25− for(c = cases; c->link != C; c = c->link) {
26− if(c->def) {
27− if(def)
28− diag(n, "more than one default in switch");
29− def = c->label;
30− continue;
31− }
32− nc++;
33− }
34−
35− iq = alloc(nc*sizeof(C1));
36− q = iq;
37− for(c = cases; c->link != C; c = c->link) {
38− if(c->def)
39− continue;
40− q->label = c->label;
41− q->val = c->val;
42− q++;
43− }
44− qsort(iq, nc, sizeof(C1), swcmp);
45− if(debug['W'])
46− for(i=0; i<nc; i++)
47− print("case %2ld: = %.8lux\n", i, iq[i].val);
48− if(def == 0)
49− def = breakpc;
50− for(i=0; i<nc-1; i++)
51− if(iq[i].val == iq[i+1].val)
52− diag(n, "duplicate cases in switch %ld", iq[i].val);
7+
538 regalloc(&tn, &regnode, Z);
54− swit1(iq, nc, def, n, &tn);
9+ swit2(q, nc, def, n, &tn);
5510 regfree(&tn);
5611 }
5712
5813 void
59−swit1(C1 *q, int nc, long def, Node *n, Node *tn)
14+swit2(C1 *q, int nc, long def, Node *n, Node *tn)
6015 {
6116 C1 *r;
6217 int i;
@@ -84,22 +39,12 @@ swit1(C1 *q, int nc, long def, Node *n, Node *tn) · 21 unmodified lines
8439 sp = p;
8540 gopcode(OEQ, n, tn, Z);
8641 patch(p, r->label);
87− swit1(q, i, def, n, tn);
42+ swit2(q, i, def, n, tn);
8843
8944 if(debug['W'])
9045 print("case < %.8lux\n", r->val);
9146 patch(sp, pc);
92− swit1(r+1, nc-i-1, def, n, tn);
93−}
94−
95−void
96−casf(void)
97−{
98− Case *c;
99−
100− c = alloc(sizeof(*c));
101− c->link = cases;
102− cases = c;
47+ swit2(r+1, nc-i-1, def, n, tn);
10348 }
10449
10550 void
@@ -197,31 +142,6 @@ outstring(char *s, long n) · 91 unmodified lines
197142 return r;
198143 }
199144
200−long
201−outlstring(ushort *s, long n)
202−{
203− char buf[2];
204− int c;
205− long r;
206−
207− while(nstring & 1)
208− outstring("", 1);
209− r = nstring;
210− while(n > 0) {
211− c = *s++;
212− if(align(0, types[TCHAR], Aarg1)) {
213− buf[0] = c>>8;
214− buf[1] = c;
215− } else {
216− buf[0] = c;
217− buf[1] = c>>8;
218− }
219− outstring(buf, 2);
220− n -= sizeof(ushort);
221− }
222− return r;
223−}
224−
225145 int
226146 mulcon(Node *n, Node *nn)
227147 {
@@ -313,16 +233,6 @@ loop: · 85 unmodified lines
313233 goto loop;
314234 }
315235
316−void
317−nullwarn(Node *l, Node *r)
318−{
319− warn(Z, "result of operation not used");
320− if(l != Z)
321− cgen(l, Z);
322− if(r != Z)
323− cgen(r, Z);
324−}
325−
326236 void
327237 sextern(Sym *s, Node *a, long o, long w)
328238 {
@@ -615,35 +525,6 @@ zaddr(char *bp, Adr *a, int s) · 286 unmodified lines
615525 return bp;
616526 }
617527
618−void
619−ieeedtod(Ieee *ieee, double native)
620−{
621− double fr, ho, f;
622− int exp;
623−
624− if(native < 0) {
625− ieeedtod(ieee, -native);
626− ieee->h |= 0x80000000L;
627− return;
628− }
629− if(native == 0) {
630− ieee->l = 0;
631− ieee->h = 0;
632− return;
633− }
634− fr = frexp(native, &exp);
635− f = 2097152L; /* shouldnt use fp constants here */
636− fr = modf(fr*f, &ho);
637− ieee->h = ho;
638− ieee->h &= 0xfffffL;
639− ieee->h |= (exp+1022L) << 20;
640− f = 65536L;
641− fr = modf(fr*f, &ho);
642− ieee->l = ho;
643− ieee->l <<= 16;
644− ieee->l |= (long)(fr*f);
645−}
646−
647528 long
648529 align(long i, Type *t, int op)
649530 {
@@ -660,6 +541,8 @@ align(long i, Type *t, int op) · 10 unmodified lines
660541
661542 case Asu2: /* padding at end of a struct */
662543 w = SZ_LONG;
544+ if(packflg)
545+ w = packflg;
663546 break;
664547
665548 case Ael1: /* initial allign of struct element */
@@ -668,6 +551,8 @@ align(long i, Type *t, int op) · 2 unmodified lines
668551 w = ewidth[v->etype];
669552 if(w <= 0 || w >= SZ_LONG)
670553 w = SZ_LONG;
554+ if(packflg)
555+ w = packflg;
671556 break;
672557
673558 case Ael2: /* width of a struct element */
@@ -687,7 +572,8 @@ align(long i, Type *t, int op) · 13 unmodified lines
687572 w = SZ_LONG;
688573 break;
689574 }
690− o += SZ_LONG - w; /* big endian adjustment */
575+ if(thechar == 'v')
576+ o += SZ_LONG - w; /* big endian adjustment */
691577 w = 1;
692578 break;
693579