|
|
1.1 root 1: #include <u.h>
2: #include <libc.h>
3: #include <bio.h>
4: #include <ctype.h>
5: #define Extern extern
6: #include "parl.h"
7: #include "globl.h"
8:
9: #define COL1 32
10:
11: Node dummy;
12:
13: int
14: sval(long v)
15: {
16:
17: if(v >= -(1<<12) && v < (1<<12))
18: return 1;
19: return 0;
20: }
21:
22: Reg*
23: rega(void)
24: {
25: Reg *r;
26:
27: r = freer;
28: if(r == R)
29: r = malloc(sizeof(Reg));
30: else
31: freer = r->next;
32:
33: *r = zreg;
34: return r;
35: }
36:
37: int
38: rcmp(void *a1, void *a2)
39: {
40: Rgn *p1, *p2;
41: int c1, c2;
42:
43: p1 = a1;
44: p2 = a2;
45: c1 = p2->cost;
46: c2 = p1->cost;
47: if(c1 -= c2)
48: return c1;
49: return p2->varno - p1->varno;
50: }
51:
52: void
53: regopt(Inst *p)
54: {
55: Reg *r, *r1, *r2;
56: int i, z;
57: long initpc, val;
58: ulong vreg;
59: Bits bit;
60: Inst *p1;
61: struct
62: {
63: long m;
64: long c;
65: Reg* p;
66: } log5[6], *lp;
67:
68: initpc = 0;
69: firstr = R;
70: lastr = R;
71: nvar = 0;
72: regbits = 0;
73: for(z=0; z<BITS; z++) {
74: externs.b[z] = 0;
75: param.b[z] = 0;
76: consts.b[z] = 0;
77: addrs.b[z] = 0;
78: }
79:
80: /*
81: * pass 1
82: * build aux data structure
83: * allocate pcs
84: * find use and set of variables
85: */
86: val = 5L * 5L * 5L * 5L * 5L;
87: lp = log5;
88: for(i=0; i<5; i++) {
89: lp->m = val;
90: lp->c = 0;
91: lp->p = R;
92: val /= 5L;
93: lp++;
94: }
95:
96: for(; p != P; p = p->next) {
97: switch(p->op) {
98: case ADATA:
99: case ADYNT:
100: case AINIT:
101: case AGLOBL:
102: case ANAME:
103: continue;
104: }
105: r = rega();
106: if(firstr == R) {
107: initpc = p->pc;
108: firstr = r;
109: lastr = r;
110: } else {
111: lastr->next = r;
112: r->p1 = lastr;
113: lastr->s1 = r;
114: lastr = r;
115: }
116: r->prog = p;
117: r->pc = p->pc;
118:
119: lp = log5;
120: for(i=0; i<5; i++) {
121: lp->c--;
122: if(lp->c <= 0) {
123: lp->c = lp->m;
124: if(lp->p != R)
125: lp->p->log5 = r;
126: lp->p = r;
127: (lp+1)->c = 0;
128: break;
129: }
130: lp++;
131: }
132:
133: r1 = r->p1;
134: if(r1 != R)
135: switch(r1->prog->op) {
136: case ARETURN:
137: case AJMP:
138: case ARETT:
139: r->p1 = R;
140: r1->s1 = R;
141: }
142:
143: /*
144: * left side always read
145: */
146: bit = mkvar(&p->src1, p->op==AMOVW);
147: for(z=0; z<BITS; z++)
148: r->use1.b[z] |= bit.b[z];
149:
150: /*
151: * right side depends on opcode
152: */
153: bit = mkvar(&p->dst, 0);
154: if(bany(&bit))
155: switch(p->op) {
156: default:
157: diag(ZeroN, "reg: unknown op: %d", p->op);
158: break;
159:
160: /*
161: * right side write
162: */
163: case ANOP:
164: case AMOVB:
165: case AMOVBU:
166: case AMOVH:
167: case AMOVHU:
168: case AMOVW:
169: case AFMOVF:
170: for(z=0; z<BITS; z++)
171: r->set.b[z] |= bit.b[z];
172: break;
173:
174: /*
175: * funny
176: */
177: case AFMOVD:
178: case ARETURN:
179: case AJMPL:
180: for(z=0; z<BITS; z++)
181: addrs.b[z] |= bit.b[z];
182: break;
183: }
184: }
185: if(firstr == R)
186: return;
187:
188: /*
189: * pass 2
190: * turn branch references to pointers
191: * build back pointers
192: */
193: for(r = firstr; r != R; r = r->next) {
194: p = r->prog;
195: if(p->dst.type == A_BRANCH) {
196: val = p->dst.ival;
197: r1 = firstr;
198: while(r1 != R) {
199: r2 = r1->log5;
200: if(r2 != R && val >= r2->pc) {
201: r1 = r2;
202: continue;
203: }
204: if(r1->pc == val)
205: break;
206: r1 = r1->next;
207: }
208: if(r1 == R) {
209: dummy.srcline = p->lineno;
210: diag(&dummy, "ref not found\n%i", p);
211: continue;
212: }
213: if(r1 == r) {
214: dummy.srcline = p->lineno;
215: diag(&dummy, "ref to self\n%i", p);
216: continue;
217: }
218: r->s2 = r1;
219: r->p2next = r1->p2;
220: r1->p2 = r;
221: }
222: }
223: if(opt('R')) {
224: p = firstr->prog;
225: print("\n%L %a\n", p->lineno, &p->src1);
226: }
227:
228: /*
229: * pass 2.5
230: * find looping structure
231: */
232: for(r = firstr; r != R; r = r->next)
233: r->active = 0;
234: change = 0;
235: loopit(firstr);
236: if(opt('R') && opt('v')) {
237: print("\nlooping structure:\n");
238: for(r = firstr; r != R; r = r->next) {
239: print("%d:%i", r->loop, r->prog);
240: for(z=0; z<BITS; z++)
241: bit.b[z] = r->use1.b[z] |
242: r->use2.b[z] | r->set.b[z];
243: if(bany(&bit)) {
244: print("%|", COL1);
245: if(bany(&r->use1))
246: print(" u1=%B", r->use1);
247: if(bany(&r->use2))
248: print(" u2=%B", r->use2);
249: if(bany(&r->set))
250: print(" st=%B", r->set);
251: }
252: print("\n");
253: }
254: }
255:
256: /*
257: * pass 3
258: * iterate propagating usage
259: * back until flow graph is complete
260: */
261: loop1:
262: change = 0;
263: for(r = firstr; r != R; r = r->next)
264: r->active = 0;
265: for(r = firstr; r != R; r = r->next)
266: if(r->prog->op == ARETURN)
267: prop(r, zbits, zbits);
268: loop11:
269: /* pick up unreachable code */
270: i = 0;
271: for(r = firstr; r != R; r = r1) {
272: r1 = r->next;
273: if(r1 && r1->active && !r->active) {
274: prop(r, zbits, zbits);
275: i = 1;
276: }
277: }
278: if(i)
279: goto loop11;
280: if(change)
281: goto loop1;
282:
283:
284: /*
285: * pass 4
286: * iterate propagating register/variable synchrony
287: * forward until graph is complete
288: */
289: loop2:
290: change = 0;
291: for(r = firstr; r != R; r = r->next)
292: r->active = 0;
293: synch(firstr, zbits);
294: if(change)
295: goto loop2;
296:
297:
298: /*
299: * pass 5
300: * isolate regions
301: * calculate costs (paint1)
302: */
303: r = firstr;
304: if(r) {
305: for(z=0; z<BITS; z++)
306: bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
307: ~(externs.b[z] | param.b[z] | addrs.b[z] | consts.b[z]);
308: if(bany(&bit)) {
309: dummy.srcline = r->prog->lineno;
310: warn(&dummy, "used and not set: %B", bit);
311: if(opt('R') && !opt('w'))
312: print("used and not set: %B\n", bit);
313: }
314: }
315: if(opt('R') && opt('v'))
316: print("\nprop structure:\n");
317: for(r = firstr; r != R; r = r->next)
318: r->act = zbits;
319: rgp = region;
320: nregion = 0;
321: for(r = firstr; r != R; r = r->next) {
322: if(opt('R') && opt('v'))
323: print("%i\n set = %B; rah = %B; cal = %B\n",
324: r->prog, r->set, r->refahead, r->calahead);
325: for(z=0; z<BITS; z++)
326: bit.b[z] = r->set.b[z] &
327: ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
328: if(bany(&bit)) {
329: dummy.srcline = r->prog->lineno;
330: warn(&dummy, "set and not used: %B", bit);
331: if(opt('R'))
332: print("set and not used: %B\n", bit);
333: excise(r);
334: }
335: for(z=0; z<BITS; z++)
336: bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
337: while(bany(&bit)) {
338: i = bnum(bit);
339: rgp->enter = r;
340: rgp->varno = i;
341: change = 0;
342: if(opt('R') && opt('v'))
343: print("\n");
344: paint1(r, i);
345: bit.b[i/32] &= ~(1L<<(i%32));
346: if(change <= 0) {
347: if(opt('R'))
348: print("%L$%d: %B\n",
349: r->prog->lineno, change, blsh(i));
350: continue;
351: }
352: rgp->cost = change;
353: nregion++;
354: if(nregion >= NRGN) {
355: warn(ZeroN, "too many regions");
356: goto brk;
357: }
358: rgp++;
359: }
360: }
361: brk:
362: qsort(region, nregion, sizeof(region[0]), rcmp);
363:
364: /*
365: * pass 6
366: * determine used registers (paint2)
367: * replace code (paint3)
368: */
369: rgp = region;
370: for(i=0; i<nregion; i++) {
371: bit = blsh(rgp->varno);
372: vreg = paint2(rgp->enter, rgp->varno);
373: vreg = allreg(vreg, rgp);
374: if(opt('R')) {
375: if(rgp->regno >= Nreg)
376: print("%L$%d F%d: %B\n",
377: rgp->enter->prog->lineno,
378: rgp->cost,
379: rgp->regno-Nreg,
380: bit);
381: else
382: print("%L$%d R%d: %B\n",
383: rgp->enter->prog->lineno,
384: rgp->cost,
385: rgp->regno,
386: bit);
387: }
388: if(rgp->regno != 0)
389: paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
390: rgp++;
391: }
392: /*
393: * pass 7
394: * peep-hole on basic block
395: */
396: if(!opt('R') || opt('P'))
397: peep();
398:
399: /*
400: * pass 8
401: * recalculate pc
402: */
403: val = initpc;
404: for(r = firstr; r != R; r = r1) {
405: r->pc = val;
406: p = r->prog;
407: r1 = r->next;
408: p1 = P;
409: if(r1 != R)
410: p1 = r1->prog;
411:
412: while(p != p1) {
413: switch(p->op) {
414: default:
415: p->pc = val++;
416:
417: case ADATA:
418: case ADYNT:
419: case AINIT:
420: case AGLOBL:
421: case ANAME:
422: case ANOP:
423: p = p->next;
424: }
425: }
426: }
427: pc = val;
428:
429: /*
430: * last pass
431: * fix up branches
432: * free aux structures
433: */
434: if(opt('R'))
435: if(bany(&addrs))
436: print("addrs: %B\n", addrs);
437:
438: r1 = 0; /* set */
439: for(r = firstr; r != R; r = r->next) {
440: p = r->prog;
441: if(p->dst.type == A_BRANCH)
442: p->dst.ival = r->s2->pc;
443: r1 = r;
444: }
445: for(p = firstr->prog; p && p->next; p = p->next)
446: while(p->next && p->next->op == ANOP)
447: p->next = p->next->next;
448:
449: if(r1 != R) {
450: r1->next = freer;
451: freer = firstr;
452: }
453: }
454:
455: /*
456: * add mov b,rn
457: * just after r
458: */
459: void
460: addmove(Reg *r, int bn, int rn, int f)
461: {
462: Inst *p, *p1;
463: Adres *a;
464: Var *v;
465:
466: if(r->prog->op == AJMPL && r->next) {
467: p1 = r->next->prog;
468: if(p1->dst.type == A_REG && p1->dst.reg == RegSP)
469: r = r->next;
470: }
471:
472: p1 = ai();
473: *p1 = zprog;
474: p = r->prog;
475:
476: p1->next = p->next;
477: p->next = p1;
478: p1->lineno = p->lineno;
479:
480: v = var + bn;
481:
482: a = &p1->dst;
483: a->sym = v->sym;
484: a->class = v->class;
485: a->ival = v->ival;
486: a->etype = v->etype;
487: a->type = A_INDREG;
488: if(a->etype == TARRAY || a->sym == ZeroS)
489: a->type = A_CONST;
490:
491: p1->op = AMOVW;
492: if(v->etype == TCHAR)
493: p1->op = AMOVBU;
494: if(v->etype == TSINT || v->etype == TSUINT)
495: p1->op = AMOVH;
496: if(v->etype == TFLOAT)
497: p1->op = AFMOVD;
498:
499: p1->src1.type = A_REG;
500: p1->src1.reg = rn;
501: if(rn >= Nreg) {
502: p1->src1.type = A_FREG;
503: p1->src1.reg = rn-Nreg;
504: }
505: if(!f) {
506: p1->src1 = *a;
507: *a = zprog.src1;
508: a->type = A_REG;
509: a->reg = rn;
510: if(rn >= Nreg) {
511: a->type = A_FREG;
512: a->reg = rn-Nreg;
513: }
514: if(v->etype == TCHAR)
515: p1->op = AMOVBU;
516: if(v->etype == TSUINT)
517: p1->op = AMOVHU;
518: }
519: if(opt('R'))
520: print("%i%|.a%i\n", p, COL1, p1);
521: }
522:
523: Bits
524: mkvar(Adres *a, int docon)
525: {
526: Var *v;
527: int i, t, n, et, z;
528: long o;
529: Bits bit;
530: Sym *s;
531:
532: t = a->type;
533: if(t == A_REG && a->reg != Nreg)
534: regbits |= RtoB(a->reg);
535: if(t == A_FREG && a->reg != Nreg)
536: regbits |= FtoB(a->reg);
537: s = a->sym;
538: o = a->ival;
539: et = a->etype;
540: if(s == ZeroS) {
541: if(t != A_CONST || !docon || a->reg != Nreg)
542: goto none;
543: et = TINT;
544: }
545: if(t == A_CONST) {
546: if(s == ZeroS && sval(o))
547: goto none;
548: }
549:
550: if(s && s->name[0] == '.' && et == TFLOAT)
551: goto none;
552:
553: n = a->class;
554: v = var;
555: for(i=0; i<nvar; i++) {
556: if(s == v->sym)
557: if(n == v->class)
558: if(o == v->ival)
559: goto out;
560: v++;
561: }
562: if(nvar >= NVAR) {
563: if(s)
564: warn(ZeroN, "variable not optimized: %s", s->name);
565: goto none;
566: }
567: i = nvar;
568: nvar++;
569: v = &var[i];
570: v->sym = s;
571: v->ival = o;
572: v->etype = et;
573: v->class = n;
574: if(opt('R'))
575: print("bit=%2d et=%2d %a\n", i, et, a);
576: out:
577: bit = blsh(i);
578: if(n == External || n == Internal || n == Global)
579: for(z=0; z<BITS; z++)
580: externs.b[z] |= bit.b[z];
581: if(n == Parameter)
582: for(z=0; z<BITS; z++)
583: param.b[z] |= bit.b[z];
584: if(v->etype != et || !(MSCALAR&(1<<et))) /* funny punning */
585: for(z=0; z<BITS; z++)
586: addrs.b[z] |= bit.b[z];
587: if(t == A_CONST) {
588: if(s == ZeroS) {
589: for(z=0; z<BITS; z++)
590: consts.b[z] |= bit.b[z];
591: return bit;
592: }
593: if(et != TARRAY)
594: for(z=0; z<BITS; z++)
595: addrs.b[z] |= bit.b[z];
596: for(z=0; z<BITS; z++)
597: param.b[z] |= bit.b[z];
598: return bit;
599: }
600: if(t == A_INDREG)
601: return bit;
602:
603: none:
604: return zbits;
605: }
606:
607: void
608: prop(Reg *r, Bits ref, Bits cal)
609: {
610: Reg *r1, *r2;
611: int z;
612:
613: for(r1 = r; r1 != R; r1 = r1->p1) {
614: for(z=0; z<BITS; z++) {
615: ref.b[z] |= r1->refahead.b[z];
616: if(ref.b[z] != r1->refahead.b[z]) {
617: r1->refahead.b[z] = ref.b[z];
618: change++;
619: }
620: cal.b[z] |= r1->calahead.b[z];
621: if(cal.b[z] != r1->calahead.b[z]) {
622: r1->calahead.b[z] = cal.b[z];
623: change++;
624: }
625: }
626: switch(r1->prog->op) {
627: case AJMPL:
628: for(z=0; z<BITS; z++) {
629: cal.b[z] |= ref.b[z] | externs.b[z];
630: ref.b[z] = 0;
631: }
632: break;
633:
634: case ATEXT:
635: for(z=0; z<BITS; z++) {
636: cal.b[z] = 0;
637: ref.b[z] = 0;
638: }
639: break;
640:
641: case ARETURN:
642: for(z=0; z<BITS; z++) {
643: cal.b[z] = externs.b[z];
644: ref.b[z] = 0;
645: }
646: }
647: for(z=0; z<BITS; z++) {
648: ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
649: r1->use1.b[z] | r1->use2.b[z];
650: cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
651: r1->refbehind.b[z] = ref.b[z];
652: r1->calbehind.b[z] = cal.b[z];
653: }
654: if(r1->active)
655: break;
656: r1->active = 1;
657: }
658: for(; r != r1; r = r->p1)
659: for(r2 = r->p2; r2 != R; r2 = r2->p2next)
660: prop(r2, r->refbehind, r->calbehind);
661: }
662:
663: int
664: loopit(Reg *r)
665: {
666: Reg *r1;
667: int l, m;
668:
669: l = 0;
670: r->active = 1;
671: r->loop = 0;
672: if(r1 = r->s1)
673: switch(r1->active) {
674: case 0:
675: l += loopit(r1);
676: break;
677: case 1:
678: l += LOOP;
679: r1->loop += LOOP;
680: }
681: if(r1 = r->s2)
682: switch(r1->active) {
683: case 0:
684: l += loopit(r1);
685: break;
686: case 1:
687: l += LOOP;
688: r1->loop += LOOP;
689: }
690: r->active = 2;
691: m = r->loop;
692: r->loop = l + 1;
693: return l - m;
694: }
695:
696: void
697: synch(Reg *r, Bits dif)
698: {
699: Reg *r1;
700: int z;
701:
702: for(r1 = r; r1 != R; r1 = r1->s1) {
703: for(z=0; z<BITS; z++) {
704: dif.b[z] = (dif.b[z] &
705: ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
706: r1->set.b[z] | r1->regdiff.b[z];
707: if(dif.b[z] != r1->regdiff.b[z]) {
708: r1->regdiff.b[z] = dif.b[z];
709: change++;
710: }
711: }
712: if(r1->active)
713: break;
714: r1->active = 1;
715: for(z=0; z<BITS; z++)
716: dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
717: if(r1->s2 != R)
718: synch(r1->s2, dif);
719: }
720: }
721:
722: ulong
723: allreg(ulong b, Rgn *r)
724: {
725: Var *v;
726: int i;
727:
728: v = var + r->varno;
729: r->regno = 0;
730: switch(v->etype) {
731:
732: default:
733: diag(ZeroN, "unknown etype %d/%d", bitno(b), v->etype);
734: break;
735:
736: case TCHAR:
737: case TSINT:
738: case TSUINT:
739: case TINT:
740: case TUINT:
741: case TIND:
742: case TARRAY:
743: i = BtoR(~b);
744: if(i && r->cost > 0) {
745: r->regno = i;
746: return RtoB(i);
747: }
748: break;
749:
750: case TFLOAT:
751: i = BtoF(~b);
752: if(i && r->cost > 0) {
753: r->regno = i+Nreg;
754: return FtoB(i);
755: }
756: break;
757: }
758: return 0;
759: }
760:
761: void
762: paint1(Reg *r, int bn)
763: {
764: Reg *r1;
765: Inst *p;
766: int z;
767: ulong bb;
768:
769: z = bn/32;
770: bb = 1L<<(bn%32);
771: if(r->act.b[z] & bb)
772: return;
773: for(;;) {
774: if(!(r->refbehind.b[z] & bb))
775: break;
776: r1 = r->p1;
777: if(r1 == R)
778: break;
779: if(!(r1->refahead.b[z] & bb))
780: break;
781: if(r1->act.b[z] & bb)
782: break;
783: r = r1;
784: }
785:
786: if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
787: change -= CLOAD * r->loop;
788: if(opt('R') && opt('v'))
789: print("%d%i%|ld %B $%d\n", r->loop,
790: r->prog, COL1, blsh(bn), change);
791: }
792: for(;;) {
793: r->act.b[z] |= bb;
794: p = r->prog;
795:
796: if(r->use1.b[z] & bb) {
797: change += CREF * r->loop;
798: if(p->dst.type == A_FREG && p->op == AMOVW)
799: change = -CINF; /* cant go Rreg to Freg */
800: if(opt('R') && opt('v'))
801: print("%d%i%|u1 %B $%d\n", r->loop,
802: p, COL1, blsh(bn), change);
803: }
804:
805: if((r->use2.b[z]|r->set.b[z]) & bb) {
806: change += CREF * r->loop;
807: if(p->src1.type == A_FREG && p->op == AMOVW)
808: change = -CINF; /* cant go Rreg to Freg */
809: if(opt('R') && opt('v'))
810: print("%d%i%|u2 %B $%d\n", r->loop,
811: p, COL1, blsh(bn), change);
812: }
813:
814: if(STORE(r) & r->regdiff.b[z] & bb) {
815: change -= CLOAD * r->loop;
816: if(opt('R') && opt('v'))
817: print("%d%i%|st %B $%d\n", r->loop,
818: p, COL1, blsh(bn), change);
819: }
820:
821: if(r->refbehind.b[z] & bb)
822: for(r1 = r->p2; r1 != R; r1 = r1->p2next)
823: if(r1->refahead.b[z] & bb)
824: paint1(r1, bn);
825:
826: if(!(r->refahead.b[z] & bb))
827: break;
828: r1 = r->s2;
829: if(r1 != R)
830: if(r1->refbehind.b[z] & bb)
831: paint1(r1, bn);
832: r = r->s1;
833: if(r == R)
834: break;
835: if(r->act.b[z] & bb)
836: break;
837: if(!(r->refbehind.b[z] & bb))
838: break;
839: }
840: }
841:
842: ulong
843: paint2(Reg *r, int bn)
844: {
845: Reg *r1;
846: int z;
847: ulong bb, vreg;
848:
849: z = bn/32;
850: bb = 1L << (bn%32);
851: vreg = regbits;
852: if(!(r->act.b[z] & bb))
853: return vreg;
854: for(;;) {
855: if(!(r->refbehind.b[z] & bb))
856: break;
857: r1 = r->p1;
858: if(r1 == R)
859: break;
860: if(!(r1->refahead.b[z] & bb))
861: break;
862: if(!(r1->act.b[z] & bb))
863: break;
864: r = r1;
865: }
866: for(;;) {
867: r->act.b[z] &= ~bb;
868:
869: vreg |= r->regu;
870:
871: if(r->refbehind.b[z] & bb)
872: for(r1 = r->p2; r1 != R; r1 = r1->p2next)
873: if(r1->refahead.b[z] & bb)
874: vreg |= paint2(r1, bn);
875:
876: if(!(r->refahead.b[z] & bb))
877: break;
878: r1 = r->s2;
879: if(r1 != R)
880: if(r1->refbehind.b[z] & bb)
881: vreg |= paint2(r1, bn);
882: r = r->s1;
883: if(r == R)
884: break;
885: if(!(r->act.b[z] & bb))
886: break;
887: if(!(r->refbehind.b[z] & bb))
888: break;
889: }
890: return vreg;
891: }
892:
893: void
894: paint3(Reg *r, int bn, long rb, int rn)
895: {
896: Reg *r1;
897: Inst *p;
898: int z;
899: ulong bb;
900:
901: z = bn/32;
902: bb = 1L << (bn%32);
903: if(r->act.b[z] & bb)
904: return;
905: for(;;) {
906: if(!(r->refbehind.b[z] & bb))
907: break;
908: r1 = r->p1;
909: if(r1 == R)
910: break;
911: if(!(r1->refahead.b[z] & bb))
912: break;
913: if(r1->act.b[z] & bb)
914: break;
915: r = r1;
916: }
917:
918: if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
919: addmove(r, bn, rn, 0);
920: for(;;) {
921: r->act.b[z] |= bb;
922: p = r->prog;
923:
924: if(r->use1.b[z] & bb) {
925: if(opt('R'))
926: print("%i", p);
927: addreg(&p->src1, rn);
928: if(opt('R'))
929: print("%|.c%i\n", COL1, p);
930: }
931: if((r->use2.b[z]|r->set.b[z]) & bb) {
932: if(opt('R'))
933: print("%i", p);
934: addreg(&p->dst, rn);
935: if(opt('R'))
936: print("%|.c%i\n", COL1, p);
937: }
938:
939: if(STORE(r) & r->regdiff.b[z] & bb)
940: addmove(r, bn, rn, 1);
941: r->regu |= rb;
942:
943: if(r->refbehind.b[z] & bb)
944: for(r1 = r->p2; r1 != R; r1 = r1->p2next)
945: if(r1->refahead.b[z] & bb)
946: paint3(r1, bn, rb, rn);
947:
948: if(!(r->refahead.b[z] & bb))
949: break;
950: r1 = r->s2;
951: if(r1 != R)
952: if(r1->refbehind.b[z] & bb)
953: paint3(r1, bn, rb, rn);
954: r = r->s1;
955: if(r == R)
956: break;
957: if(r->act.b[z] & bb)
958: break;
959: if(!(r->refbehind.b[z] & bb))
960: break;
961: }
962: }
963:
964: void
965: addreg(Adres *a, int rn)
966: {
967: a->sym = 0;
968: a->type = A_REG;
969: a->class = 0;
970: a->reg = rn;
971: if(rn >= Nreg) {
972: a->type = A_FREG;
973: a->reg = rn-Nreg;
974: }
975: }
976:
977: /*
978: * bit reg
979: * 0 R9
980: * 1 R10
981: * ... ...
982: * 4 R13
983: * 5 R16
984: * ... ...
985: * 20 R31
986: */
987: long
988: RtoB(int r)
989: {
990:
991: if(r >= 9 && r <= 13)
992: return 1L << (r-9);
993: if(r >= 16 && r <= 31)
994: return 1L << (r-11);
995: return 0;
996: }
997:
998: int
999: BtoR(long b)
1000: {
1001: int r;
1002:
1003: b &= 0x001fffffL;
1004: if(b == 0)
1005: return 0;
1006: r = bitno(b) + 9;
1007: if(r >= 14)
1008: r += 2;
1009: return r;
1010: }
1011:
1012: /*
1013: * bit reg
1014: * 22 F4
1015: * 23 F6
1016: * ... ...
1017: * 31 F22
1018: */
1019: long
1020: FtoB(int f)
1021: {
1022:
1023: if(f < 4 || f > 22 || (f&1))
1024: return 0;
1025: return 1L << (f/2 + 20);
1026: }
1027:
1028: BtoF(long b)
1029: {
1030:
1031: b &= 0xffc00000L;
1032: if(b == 0)
1033: return 0;
1034: return bitno(b)*2 - 40;
1035: }
1036:
1037: int
1038: bany(Bits *a)
1039: {
1040: int i;
1041:
1042: for(i=0; i<BITS; i++)
1043: if(a->b[i])
1044: return 1;
1045: return 0;
1046: }
1047:
1048: int
1049: bnum(Bits a)
1050: {
1051: int i;
1052: long b;
1053:
1054: for(i=0; i<BITS; i++)
1055: if(b = a.b[i])
1056: return 32*i + bitno(b);
1057: diag(ZeroN, "bad in bnum");
1058: return 0;
1059: }
1060:
1061: Bits
1062: blsh(int n)
1063: {
1064: Bits c;
1065:
1066: c = zbits;
1067: c.b[n/32] = 1L << (n%32);
1068: return c;
1069: }
1070:
1071: int
1072: Bconv(void *o, Fconv *f)
1073: {
1074: char str[128], ss[128], *s;
1075: Bits bits;
1076: int i;
1077:
1078: str[0] = 0;
1079: bits = *(Bits*)o;
1080: while(bany(&bits)) {
1081: i = bnum(bits);
1082: if(str[0])
1083: strcat(str, " ");
1084: if(var[i].sym == ZeroS) {
1085: sprint(ss, "$%ld", var[i].ival);
1086: s = ss;
1087: } else
1088: s = var[i].sym->name;
1089: if(strlen(str) + strlen(s) + 1 >= 128)
1090: break;
1091: strcat(str, s);
1092: bits.b[i/32] &= ~(1L << (i%32));
1093: }
1094: strconv(str, f);
1095: return sizeof(bits);
1096: }
1097:
1098: int
1099: bitno(long b)
1100: {
1101: int i;
1102:
1103: for(i=0; i<32; i++)
1104: if(b & (1L<<i))
1105: return i;
1106: diag(ZeroN, "bad in bitno");
1107: return 0;
1108: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.