17edc7532SDavid du Colombier #include "l.h"
27edc7532SDavid du Colombier
37edc7532SDavid du Colombier void
noops(void)47edc7532SDavid du Colombier noops(void)
57edc7532SDavid du Colombier {
67edc7532SDavid du Colombier Prog *p, *p1, *q, *q1;
77edc7532SDavid du Colombier int o, curframe, curbecome, maxbecome;
87edc7532SDavid du Colombier
97edc7532SDavid du Colombier /*
107edc7532SDavid du Colombier * find leaf subroutines
117edc7532SDavid du Colombier * become sizes
127edc7532SDavid du Colombier * frame sizes
137edc7532SDavid du Colombier * strip NOPs
147edc7532SDavid du Colombier * expand RET
157edc7532SDavid du Colombier * expand BECOME pseudo
167edc7532SDavid du Colombier */
177edc7532SDavid du Colombier
187edc7532SDavid du Colombier if(debug['v'])
197edc7532SDavid du Colombier Bprint(&bso, "%5.2f noops\n", cputime());
207edc7532SDavid du Colombier Bflush(&bso);
217edc7532SDavid du Colombier
227edc7532SDavid du Colombier curframe = 0;
237edc7532SDavid du Colombier curbecome = 0;
247edc7532SDavid du Colombier maxbecome = 0;
257edc7532SDavid du Colombier curtext = 0;
267edc7532SDavid du Colombier
277edc7532SDavid du Colombier q = P;
287edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
297edc7532SDavid du Colombier
307edc7532SDavid du Colombier /* find out how much arg space is used in this TEXT */
317edc7532SDavid du Colombier if(p->to.type == D_OREG && p->to.reg == REGSP)
327edc7532SDavid du Colombier if(p->to.offset > curframe)
337edc7532SDavid du Colombier curframe = p->to.offset;
347edc7532SDavid du Colombier
357edc7532SDavid du Colombier switch(p->as) {
367edc7532SDavid du Colombier case ATEXT:
377edc7532SDavid du Colombier if(curtext && curtext->from.sym) {
387edc7532SDavid du Colombier curtext->from.sym->frame = curframe;
397edc7532SDavid du Colombier curtext->from.sym->become = curbecome;
407edc7532SDavid du Colombier if(curbecome > maxbecome)
417edc7532SDavid du Colombier maxbecome = curbecome;
427edc7532SDavid du Colombier }
437edc7532SDavid du Colombier curframe = 0;
447edc7532SDavid du Colombier curbecome = 0;
457edc7532SDavid du Colombier
467edc7532SDavid du Colombier p->mark |= LABEL|LEAF|SYNC;
477edc7532SDavid du Colombier if(p->link)
487edc7532SDavid du Colombier p->link->mark |= LABEL;
497edc7532SDavid du Colombier curtext = p;
507edc7532SDavid du Colombier break;
517edc7532SDavid du Colombier
527edc7532SDavid du Colombier /* too hard, just leave alone */
537edc7532SDavid du Colombier case AMOVW:
547edc7532SDavid du Colombier case AMOVV:
557edc7532SDavid du Colombier if(p->to.type == D_FCREG ||
567edc7532SDavid du Colombier p->to.type == D_MREG) {
577edc7532SDavid du Colombier p->mark |= LABEL|SYNC;
587edc7532SDavid du Colombier break;
597edc7532SDavid du Colombier }
607edc7532SDavid du Colombier if(p->from.type == D_FCREG ||
617edc7532SDavid du Colombier p->from.type == D_MREG) {
627edc7532SDavid du Colombier p->mark |= LABEL|SYNC;
637edc7532SDavid du Colombier addnop(p);
647edc7532SDavid du Colombier addnop(p);
657edc7532SDavid du Colombier nop.mfrom.count += 2;
667edc7532SDavid du Colombier nop.mfrom.outof += 2;
677edc7532SDavid du Colombier break;
687edc7532SDavid du Colombier }
697edc7532SDavid du Colombier break;
707edc7532SDavid du Colombier
717edc7532SDavid du Colombier /* too hard, just leave alone */
727edc7532SDavid du Colombier case ACASE:
737edc7532SDavid du Colombier case ASYSCALL:
747edc7532SDavid du Colombier case AWORD:
757edc7532SDavid du Colombier case ATLBWR:
767edc7532SDavid du Colombier case ATLBWI:
777edc7532SDavid du Colombier case ATLBP:
787edc7532SDavid du Colombier case ATLBR:
797edc7532SDavid du Colombier p->mark |= LABEL|SYNC;
807edc7532SDavid du Colombier break;
817edc7532SDavid du Colombier
827edc7532SDavid du Colombier case ANOR:
837edc7532SDavid du Colombier if(p->to.type == D_REG && p->to.reg == REGZERO)
847edc7532SDavid du Colombier p->mark |= LABEL|SYNC;
857edc7532SDavid du Colombier break;
867edc7532SDavid du Colombier
877edc7532SDavid du Colombier case ARET:
887edc7532SDavid du Colombier /* special form of RET is BECOME */
897edc7532SDavid du Colombier if(p->from.type == D_CONST)
907edc7532SDavid du Colombier if(p->from.offset > curbecome)
917edc7532SDavid du Colombier curbecome = p->from.offset;
927edc7532SDavid du Colombier
937edc7532SDavid du Colombier if(p->link != P)
947edc7532SDavid du Colombier p->link->mark |= LABEL;
957edc7532SDavid du Colombier break;
967edc7532SDavid du Colombier
977edc7532SDavid du Colombier case ANOP:
987edc7532SDavid du Colombier q1 = p->link;
997edc7532SDavid du Colombier q->link = q1; /* q is non-nop */
1007edc7532SDavid du Colombier q1->mark |= p->mark;
1017edc7532SDavid du Colombier continue;
1027edc7532SDavid du Colombier
1037edc7532SDavid du Colombier case ABCASE:
1047edc7532SDavid du Colombier p->mark |= LABEL|SYNC;
1057edc7532SDavid du Colombier goto dstlab;
1067edc7532SDavid du Colombier
1077edc7532SDavid du Colombier case ABGEZAL:
1087edc7532SDavid du Colombier case ABLTZAL:
1097edc7532SDavid du Colombier case AJAL:
1107edc7532SDavid du Colombier if(curtext != P)
1117edc7532SDavid du Colombier curtext->mark &= ~LEAF;
1127edc7532SDavid du Colombier
1137edc7532SDavid du Colombier case AJMP:
1147edc7532SDavid du Colombier case ABEQ:
1157edc7532SDavid du Colombier case ABGEZ:
1167edc7532SDavid du Colombier case ABGTZ:
1177edc7532SDavid du Colombier case ABLEZ:
1187edc7532SDavid du Colombier case ABLTZ:
1197edc7532SDavid du Colombier case ABNE:
1207edc7532SDavid du Colombier case ABFPT:
1217edc7532SDavid du Colombier case ABFPF:
1227edc7532SDavid du Colombier p->mark |= BRANCH;
1237edc7532SDavid du Colombier
1247edc7532SDavid du Colombier dstlab:
1257edc7532SDavid du Colombier q1 = p->cond;
1267edc7532SDavid du Colombier if(q1 != P) {
1277edc7532SDavid du Colombier while(q1->as == ANOP) {
1287edc7532SDavid du Colombier q1 = q1->link;
1297edc7532SDavid du Colombier p->cond = q1;
1307edc7532SDavid du Colombier }
1317edc7532SDavid du Colombier if(!(q1->mark & LEAF))
1327edc7532SDavid du Colombier q1->mark |= LABEL;
1337edc7532SDavid du Colombier } else
1347edc7532SDavid du Colombier p->mark |= LABEL;
1357edc7532SDavid du Colombier q1 = p->link;
1367edc7532SDavid du Colombier if(q1 != P)
1377edc7532SDavid du Colombier q1->mark |= LABEL;
1387edc7532SDavid du Colombier break;
1397edc7532SDavid du Colombier }
1407edc7532SDavid du Colombier q = p;
1417edc7532SDavid du Colombier }
1427edc7532SDavid du Colombier
1437edc7532SDavid du Colombier if(curtext && curtext->from.sym) {
1447edc7532SDavid du Colombier curtext->from.sym->frame = curframe;
1457edc7532SDavid du Colombier curtext->from.sym->become = curbecome;
1467edc7532SDavid du Colombier if(curbecome > maxbecome)
1477edc7532SDavid du Colombier maxbecome = curbecome;
1487edc7532SDavid du Colombier }
1497edc7532SDavid du Colombier
1507edc7532SDavid du Colombier if(debug['b'])
1517edc7532SDavid du Colombier print("max become = %d\n", maxbecome);
1527edc7532SDavid du Colombier xdefine("ALEFbecome", STEXT, maxbecome);
1537edc7532SDavid du Colombier
1547edc7532SDavid du Colombier curtext = 0;
1557edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
1567edc7532SDavid du Colombier switch(p->as) {
1577edc7532SDavid du Colombier case ATEXT:
1587edc7532SDavid du Colombier curtext = p;
1597edc7532SDavid du Colombier break;
1607edc7532SDavid du Colombier case AJAL:
1617edc7532SDavid du Colombier if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
1627edc7532SDavid du Colombier o = maxbecome - curtext->from.sym->frame;
1637edc7532SDavid du Colombier if(o <= 0)
1647edc7532SDavid du Colombier break;
1657edc7532SDavid du Colombier /* calling a become or calling a variable */
1667edc7532SDavid du Colombier if(p->to.sym == S || p->to.sym->become) {
1677edc7532SDavid du Colombier curtext->to.offset += o;
1687edc7532SDavid du Colombier if(debug['b']) {
1697edc7532SDavid du Colombier curp = p;
1707edc7532SDavid du Colombier print("%D calling %D increase %d\n",
1717edc7532SDavid du Colombier &curtext->from, &p->to, o);
1727edc7532SDavid du Colombier }
1737edc7532SDavid du Colombier }
1747edc7532SDavid du Colombier }
1757edc7532SDavid du Colombier break;
1767edc7532SDavid du Colombier }
1777edc7532SDavid du Colombier }
1787edc7532SDavid du Colombier
1797edc7532SDavid du Colombier for(p = firstp; p != P; p = p->link) {
1807edc7532SDavid du Colombier o = p->as;
1817edc7532SDavid du Colombier switch(o) {
1827edc7532SDavid du Colombier case ATEXT:
1837edc7532SDavid du Colombier curtext = p;
1847edc7532SDavid du Colombier autosize = p->to.offset + 8;
1857edc7532SDavid du Colombier if(autosize <= 8)
1867edc7532SDavid du Colombier if(curtext->mark & LEAF) {
1877edc7532SDavid du Colombier p->to.offset = -8;
1887edc7532SDavid du Colombier autosize = 0;
1897edc7532SDavid du Colombier }
1907edc7532SDavid du Colombier
1917edc7532SDavid du Colombier q = p;
1927edc7532SDavid du Colombier if(autosize) {
1937edc7532SDavid du Colombier if(autosize & 7)
1947edc7532SDavid du Colombier Bprint(&bso, "odd stack in: %s\n",
1957edc7532SDavid du Colombier curtext->from.sym->name);
1967edc7532SDavid du Colombier q = prg();
197*f8bc6aafSDavid du Colombier q->as = AADDV;
1987edc7532SDavid du Colombier q->line = p->line;
1997edc7532SDavid du Colombier q->from.type = D_CONST;
2007edc7532SDavid du Colombier q->from.offset = -autosize;
2017edc7532SDavid du Colombier q->to.type = D_REG;
2027edc7532SDavid du Colombier q->to.reg = REGSP;
2037edc7532SDavid du Colombier
2047edc7532SDavid du Colombier q->link = p->link;
2057edc7532SDavid du Colombier p->link = q;
2067edc7532SDavid du Colombier } else
2077edc7532SDavid du Colombier if(!(curtext->mark & LEAF)) {
2087edc7532SDavid du Colombier if(debug['v'])
2097edc7532SDavid du Colombier Bprint(&bso, "save suppressed in: %s\n",
2107edc7532SDavid du Colombier curtext->from.sym->name);
2117edc7532SDavid du Colombier Bflush(&bso);
2127edc7532SDavid du Colombier curtext->mark |= LEAF;
2137edc7532SDavid du Colombier }
2147edc7532SDavid du Colombier
2157edc7532SDavid du Colombier if(curtext->mark & LEAF) {
2167edc7532SDavid du Colombier if(curtext->from.sym)
2177edc7532SDavid du Colombier curtext->from.sym->type = SLEAF;
2187edc7532SDavid du Colombier break;
2197edc7532SDavid du Colombier }
2207edc7532SDavid du Colombier
2217edc7532SDavid du Colombier q1 = prg();
222*f8bc6aafSDavid du Colombier q1->as = AMOVV;
2237edc7532SDavid du Colombier q1->line = p->line;
2247edc7532SDavid du Colombier q1->from.type = D_REG;
2257edc7532SDavid du Colombier q1->from.reg = REGLINK;
2267edc7532SDavid du Colombier q1->to.type = D_OREG;
2277edc7532SDavid du Colombier q1->from.offset = 0;
2287edc7532SDavid du Colombier q1->to.reg = REGSP;
2297edc7532SDavid du Colombier
2307edc7532SDavid du Colombier q1->link = q->link;
2317edc7532SDavid du Colombier q->link = q1;
2327edc7532SDavid du Colombier break;
2337edc7532SDavid du Colombier
2347edc7532SDavid du Colombier case ARET:
2357edc7532SDavid du Colombier nocache(p);
2367edc7532SDavid du Colombier if(p->from.type == D_CONST)
2377edc7532SDavid du Colombier goto become;
2387edc7532SDavid du Colombier if(curtext->mark & LEAF) {
2397edc7532SDavid du Colombier if(!autosize) {
2407edc7532SDavid du Colombier p->as = AJMP;
2417edc7532SDavid du Colombier p->from = zprg.from;
2427edc7532SDavid du Colombier p->to.type = D_OREG;
2437edc7532SDavid du Colombier p->to.offset = 0;
2447edc7532SDavid du Colombier p->to.reg = REGLINK;
2457edc7532SDavid du Colombier p->mark |= BRANCH;
2467edc7532SDavid du Colombier break;
2477edc7532SDavid du Colombier }
2487edc7532SDavid du Colombier
249*f8bc6aafSDavid du Colombier p->as = AADDV;
2507edc7532SDavid du Colombier p->from.type = D_CONST;
2517edc7532SDavid du Colombier p->from.offset = autosize;
2527edc7532SDavid du Colombier p->to.type = D_REG;
2537edc7532SDavid du Colombier p->to.reg = REGSP;
2547edc7532SDavid du Colombier
2557edc7532SDavid du Colombier q = prg();
2567edc7532SDavid du Colombier q->as = AJMP;
2577edc7532SDavid du Colombier q->line = p->line;
2587edc7532SDavid du Colombier q->to.type = D_OREG;
2597edc7532SDavid du Colombier q->to.offset = 0;
2607edc7532SDavid du Colombier q->to.reg = REGLINK;
2617edc7532SDavid du Colombier q->mark |= BRANCH;
2627edc7532SDavid du Colombier
2637edc7532SDavid du Colombier q->link = p->link;
2647edc7532SDavid du Colombier p->link = q;
2657edc7532SDavid du Colombier break;
2667edc7532SDavid du Colombier }
267*f8bc6aafSDavid du Colombier p->as = AMOVV;
2687edc7532SDavid du Colombier p->from.type = D_OREG;
2697edc7532SDavid du Colombier p->from.offset = 0;
2707edc7532SDavid du Colombier p->from.reg = REGSP;
2717edc7532SDavid du Colombier p->to.type = D_REG;
2727edc7532SDavid du Colombier p->to.reg = 2;
2737edc7532SDavid du Colombier
2747edc7532SDavid du Colombier q = p;
2757edc7532SDavid du Colombier if(autosize) {
2767edc7532SDavid du Colombier q = prg();
277*f8bc6aafSDavid du Colombier q->as = AADDV;
2787edc7532SDavid du Colombier q->line = p->line;
2797edc7532SDavid du Colombier q->from.type = D_CONST;
2807edc7532SDavid du Colombier q->from.offset = autosize;
2817edc7532SDavid du Colombier q->to.type = D_REG;
2827edc7532SDavid du Colombier q->to.reg = REGSP;
2837edc7532SDavid du Colombier
2847edc7532SDavid du Colombier q->link = p->link;
2857edc7532SDavid du Colombier p->link = q;
2867edc7532SDavid du Colombier }
2877edc7532SDavid du Colombier
2887edc7532SDavid du Colombier q1 = prg();
2897edc7532SDavid du Colombier q1->as = AJMP;
2907edc7532SDavid du Colombier q1->line = p->line;
2917edc7532SDavid du Colombier q1->to.type = D_OREG;
2927edc7532SDavid du Colombier q1->to.offset = 0;
2937edc7532SDavid du Colombier q1->to.reg = 2;
2947edc7532SDavid du Colombier q1->mark |= BRANCH;
2957edc7532SDavid du Colombier
2967edc7532SDavid du Colombier q1->link = q->link;
2977edc7532SDavid du Colombier q->link = q1;
2987edc7532SDavid du Colombier break;
2997edc7532SDavid du Colombier
3007edc7532SDavid du Colombier become:
3017edc7532SDavid du Colombier if(curtext->mark & LEAF) {
3027edc7532SDavid du Colombier
3037edc7532SDavid du Colombier q = prg();
3047edc7532SDavid du Colombier q->line = p->line;
3057edc7532SDavid du Colombier q->as = AJMP;
3067edc7532SDavid du Colombier q->from = zprg.from;
3077edc7532SDavid du Colombier q->to = p->to;
3087edc7532SDavid du Colombier q->cond = p->cond;
3097edc7532SDavid du Colombier q->link = p->link;
3107edc7532SDavid du Colombier q->mark |= BRANCH;
3117edc7532SDavid du Colombier p->link = q;
3127edc7532SDavid du Colombier
313*f8bc6aafSDavid du Colombier p->as = AADDV;
3147edc7532SDavid du Colombier p->from = zprg.from;
3157edc7532SDavid du Colombier p->from.type = D_CONST;
3167edc7532SDavid du Colombier p->from.offset = autosize;
3177edc7532SDavid du Colombier p->to = zprg.to;
3187edc7532SDavid du Colombier p->to.type = D_REG;
3197edc7532SDavid du Colombier p->to.reg = REGSP;
3207edc7532SDavid du Colombier
3217edc7532SDavid du Colombier break;
3227edc7532SDavid du Colombier }
3237edc7532SDavid du Colombier q = prg();
3247edc7532SDavid du Colombier q->line = p->line;
3257edc7532SDavid du Colombier q->as = AJMP;
3267edc7532SDavid du Colombier q->from = zprg.from;
3277edc7532SDavid du Colombier q->to = p->to;
3287edc7532SDavid du Colombier q->cond = p->cond;
3297edc7532SDavid du Colombier q->link = p->link;
3307edc7532SDavid du Colombier q->mark |= BRANCH;
3317edc7532SDavid du Colombier p->link = q;
3327edc7532SDavid du Colombier
3337edc7532SDavid du Colombier q = prg();
3347edc7532SDavid du Colombier q->line = p->line;
335*f8bc6aafSDavid du Colombier q->as = AADDV;
3367edc7532SDavid du Colombier q->from.type = D_CONST;
3377edc7532SDavid du Colombier q->from.offset = autosize;
3387edc7532SDavid du Colombier q->to.type = D_REG;
3397edc7532SDavid du Colombier q->to.reg = REGSP;
3407edc7532SDavid du Colombier q->link = p->link;
3417edc7532SDavid du Colombier p->link = q;
3427edc7532SDavid du Colombier
343*f8bc6aafSDavid du Colombier p->as = AMOVV;
3447edc7532SDavid du Colombier p->from = zprg.from;
3457edc7532SDavid du Colombier p->from.type = D_OREG;
3467edc7532SDavid du Colombier p->from.offset = 0;
3477edc7532SDavid du Colombier p->from.reg = REGSP;
3487edc7532SDavid du Colombier p->to = zprg.to;
3497edc7532SDavid du Colombier p->to.type = D_REG;
3507edc7532SDavid du Colombier p->to.reg = REGLINK;
3517edc7532SDavid du Colombier
3527edc7532SDavid du Colombier break;
3537edc7532SDavid du Colombier }
3547edc7532SDavid du Colombier }
3557edc7532SDavid du Colombier
3567edc7532SDavid du Colombier curtext = P;
3577edc7532SDavid du Colombier q = P; /* p - 1 */
3587edc7532SDavid du Colombier q1 = firstp; /* top of block */
3597edc7532SDavid du Colombier o = 0; /* count of instructions */
3607edc7532SDavid du Colombier for(p = firstp; p != P; p = p1) {
3617edc7532SDavid du Colombier p1 = p->link;
3627edc7532SDavid du Colombier o++;
3637edc7532SDavid du Colombier if(p->mark & NOSCHED){
3647edc7532SDavid du Colombier if(q1 != p){
3657edc7532SDavid du Colombier sched(q1, q);
3667edc7532SDavid du Colombier }
3677edc7532SDavid du Colombier for(; p != P; p = p->link){
3687edc7532SDavid du Colombier if(!(p->mark & NOSCHED))
3697edc7532SDavid du Colombier break;
3707edc7532SDavid du Colombier q = p;
3717edc7532SDavid du Colombier }
3727edc7532SDavid du Colombier p1 = p;
3737edc7532SDavid du Colombier q1 = p;
3747edc7532SDavid du Colombier o = 0;
3757edc7532SDavid du Colombier continue;
3767edc7532SDavid du Colombier }
3777edc7532SDavid du Colombier if(p->mark & (LABEL|SYNC)) {
3787edc7532SDavid du Colombier if(q1 != p)
3797edc7532SDavid du Colombier sched(q1, q);
3807edc7532SDavid du Colombier q1 = p;
3817edc7532SDavid du Colombier o = 1;
3827edc7532SDavid du Colombier }
3837edc7532SDavid du Colombier if(p->mark & (BRANCH|SYNC)) {
3847edc7532SDavid du Colombier sched(q1, p);
3857edc7532SDavid du Colombier q1 = p1;
3867edc7532SDavid du Colombier o = 0;
3877edc7532SDavid du Colombier }
3887edc7532SDavid du Colombier if(o >= NSCHED) {
3897edc7532SDavid du Colombier sched(q1, p);
3907edc7532SDavid du Colombier q1 = p1;
3917edc7532SDavid du Colombier o = 0;
3927edc7532SDavid du Colombier }
3937edc7532SDavid du Colombier q = p;
3947edc7532SDavid du Colombier }
3957edc7532SDavid du Colombier }
3967edc7532SDavid du Colombier
3977edc7532SDavid du Colombier void
addnop(Prog * p)3987edc7532SDavid du Colombier addnop(Prog *p)
3997edc7532SDavid du Colombier {
4007edc7532SDavid du Colombier Prog *q;
4017edc7532SDavid du Colombier
4027edc7532SDavid du Colombier q = prg();
4037edc7532SDavid du Colombier q->as = ANOR;
4047edc7532SDavid du Colombier q->line = p->line;
4057edc7532SDavid du Colombier q->from.type = D_REG;
4067edc7532SDavid du Colombier q->from.reg = REGZERO;
4077edc7532SDavid du Colombier q->to.type = D_REG;
4087edc7532SDavid du Colombier q->to.reg = REGZERO;
4097edc7532SDavid du Colombier
4107edc7532SDavid du Colombier q->link = p->link;
4117edc7532SDavid du Colombier p->link = q;
4127edc7532SDavid du Colombier }
4137edc7532SDavid du Colombier
4147edc7532SDavid du Colombier void
nocache(Prog * p)4157edc7532SDavid du Colombier nocache(Prog *p)
4167edc7532SDavid du Colombier {
4177edc7532SDavid du Colombier p->optab = 0;
4187edc7532SDavid du Colombier p->from.class = 0;
4197edc7532SDavid du Colombier p->to.class = 0;
4207edc7532SDavid du Colombier }
421