]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/7l/noop.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / 7l / noop.c
index e7f9b655b4729fa66d752648df9e97dfd3ecf29e..b61ac3f4d4544d583ae3e4a7b0d14e1a4cb04805 100644 (file)
@@ -1,24 +1,18 @@
 #include       "l.h"
 
-Prog   *divuconst(Prog *, uvlong, int, int, int);
-Prog   *divconst(Prog *, vlong, int, int, int);
-Prog   *modconst(Prog *, vlong, int, int, int);
-void   excise(Prog *);
-
 void
 noops(void)
 {
-       Prog *p, *p1, *q, *q1, *q2;
-       int o, curframe, curbecome, maxbecome, shift;
+       Prog *p, *q, *q1;
+       int o, aoffset, curframe, curbecome, maxbecome;
 
        /*
         * find leaf subroutines
         * become sizes
         * frame sizes
         * strip NOPs
-        * expand RET and other macros
+        * expand RET
         * expand BECOME pseudo
-        * use conditional moves where appropriate
         */
 
        if(debug['v'])
@@ -49,32 +43,15 @@ noops(void)
                        curframe = 0;
                        curbecome = 0;
 
-                       p->mark |= LABEL|LEAF|SYNC;
-                       if(p->link)
-                               p->link->mark |= LABEL;
+                       p->mark |= LEAF;
                        curtext = p;
                        break;
 
-               /* don't mess with what we don't understand */
-               case AWORD:
-               case ACALL_PAL:
-               /* etc. */
-                       p->mark |= LABEL;
-                       for(q1=p->link; q1 != P; q1 = q1->link) {
-                               q1->mark |= LABEL;
-                               if(q1->as != AXORNOT)           /* used as NOP in PALcode */
-                                       break;
-                       }
-                       break;
-
-               case ARET:
-                       /* special form of RET is BECOME */
+               case ARETURN:
+                       /* special form of RETURN is BECOME */
                        if(p->from.type == D_CONST)
                                if(p->from.offset > curbecome)
                                        curbecome = p->from.offset;
-
-                       if(p->link != P)
-                               p->link->mark |= LABEL;
                        break;
 
                case ANOP:
@@ -83,64 +60,47 @@ noops(void)
                        q1->mark |= p->mark;
                        continue;
 
-               case AJSR:
+               case ABL:
                        if(curtext != P)
                                curtext->mark &= ~LEAF;
+
+               case ACBNZ:
+               case ACBZ:
+               case ACBNZW:
+               case ACBZW:
+               case ATBZ:
+               case ATBNZ:
+
+               case ABCASE:
+               case AB:
+
                case ABEQ:
                case ABNE:
+               case ABCS:
+               case ABHS:
+               case ABCC:
+               case ABLO:
+               case ABMI:
+               case ABPL:
+               case ABVS:
+               case ABVC:
+               case ABHI:
+               case ABLS:
                case ABGE:
+               case ABLT:
                case ABGT:
                case ABLE:
-               case ABLT:
-               case ABLBC:
-               case ABLBS:
-               case AFBEQ:
-               case AFBNE:
-               case AFBGE:
-               case AFBGT:
-               case AFBLE:
-               case AFBLT:
-               case AJMP:
-                       p->mark |= BRANCH;
+
+               case AADR:              /* strange */
+               case AADRP:
+
                        q1 = p->cond;
                        if(q1 != P) {
                                while(q1->as == ANOP) {
                                        q1 = q1->link;
                                        p->cond = q1;
                                }
-                               if(!(q1->mark & LEAF)) {
-                                       if (q1->mark & LABEL)
-                                               q1->mark |= LABEL2;
-                                       else
-                                               q1->mark |= LABEL;
-                               }
-                       } else
-                               p->mark |= LABEL;
-                       q1 = p->link;
-                       if(q1 != P) {
-                               if (q1->mark & LABEL)
-                                       q1->mark |= LABEL2;
-                               else
-                                       q1->mark |= LABEL;
                        }
-                       else
-                               p->mark |= LABEL;       /* ??? */
-                       break;
-
-               case ADIVQ:
-               case ADIVQU:
-               case AMODQ:
-               case AMODQU:
-               case ADIVL:
-               case ADIVLU:
-               case AMODL:
-               case AMODLU:
-                       if(p->from.type == D_CONST /*&& !debug['d']*/)
-                               continue;
-                       if(prog_divq == P)
-                               initdiv();
-                       if(curtext != P)
-                               curtext->mark &= ~LEAF;
                        break;
                }
                q = p;
@@ -163,7 +123,7 @@ noops(void)
                case ATEXT:
                        curtext = p;
                        break;
-               case AJSR:
+               case ABL:
                        if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
                                o = maxbecome - curtext->from.sym->frame;
                                if(o <= 0)
@@ -187,19 +147,17 @@ noops(void)
                switch(o) {
                case ATEXT:
                        curtext = p;
-                       autosize = p->to.offset + 8;
-                       if(autosize <= 8)
-                       if(curtext->mark & LEAF) {
-                               p->to.offset = -8;
+                       if(p->to.offset < 0)
                                autosize = 0;
-                       }
-                       if (autosize & 4)
-                               autosize += 4;
+                       else
+                               autosize = p->to.offset + PCSZ;
+                       if((curtext->mark & LEAF) && autosize <= PCSZ)
+                               autosize = 0;
+                       else if(autosize & (STACKALIGN-1))
+                               autosize += STACKALIGN - (autosize&(STACKALIGN-1));
+                       p->to.offset = autosize - PCSZ;
 
-                       q = p;
-                       if(autosize)
-                               q = genIRR(p, ASUBQ, autosize, NREG, REGSP);
-                       else if(!(curtext->mark & LEAF)) {
+                       if(autosize == 0 && !(curtext->mark & LEAF)) {
                                if(debug['v'])
                                        Bprint(&bso, "save suppressed in: %s\n",
                                                curtext->from.sym->name);
@@ -207,84 +165,122 @@ noops(void)
                                curtext->mark |= LEAF;
                        }
 
+                       aoffset = autosize;
+                       if(aoffset > 0xF0)
+                               aoffset = 0xF0;
+
                        if(curtext->mark & LEAF) {
                                if(curtext->from.sym)
                                        curtext->from.sym->type = SLEAF;
-                               break;
+                               if(autosize == 0)
+                                       break;
+                               aoffset = 0;
                        }
 
-                       genstore(q, AMOVL, REGLINK, 0LL, REGSP);
+                       q = p;
+                       if(autosize > aoffset){
+                               q = prg();
+                               q->as = ASUB;
+                               q->line = p->line;
+                               q->from.type = D_CONST;
+                               q->from.offset = autosize - aoffset;
+                               q->to.type = D_REG;
+                               q->to.reg = REGSP;
+                               q->link = p->link;
+                               p->link = q;
+
+                               if(curtext->mark & LEAF)
+                                       break;
+                       }
+
+                       q1 = prg();
+                       q1->as = AMOV;
+                       q1->line = p->line;
+                       q1->from.type = D_REG;
+                       q1->from.reg = REGLINK;
+                       q1->to.type = D_XPRE;
+                       q1->to.offset = -aoffset;
+                       q1->to.reg = REGSP;
+
+                       q1->link = q->link;
+                       q->link = q1;
                        break;
 
-               case ARET:
+               case ARETURN:
                        nocache(p);
                        if(p->from.type == D_CONST)
                                goto become;
                        if(curtext->mark & LEAF) {
-                               if(!autosize) {
-                                       p->as = AJMP;
-                                       p->from = zprg.from;
-                                       p->to.type = D_OREG;
-                                       p->to.offset = 0;
-                                       p->to.reg = REGLINK;
-                                       break;
+                               if(autosize != 0){
+                                       p->as = AADD;
+                                       p->from.type = D_CONST;
+                                       p->from.offset = autosize;
+                                       p->to.type = D_REG;
+                                       p->to.reg = REGSP;
                                }
-
-                               p->as = AADDQ;
-                               p->from.type = D_CONST;
-                               p->from.offset = autosize;
+                       }else{
+                               /* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
+                               aoffset = autosize;
+                               if(aoffset > 0xF0)
+                                       aoffset = 0xF0;
+
+                               p->as = AMOV;
+                               p->from.type = D_XPOST;
+                               p->from.offset = aoffset;
+                               p->from.reg = REGSP;
                                p->to.type = D_REG;
-                               p->to.reg = REGSP;
+                               p->to.reg = REGLINK;
+
+                               if(autosize > aoffset) {
+                                       q = prg();
+                                       q->as = AADD;
+                                       q->from.type = D_CONST;
+                                       q->from.offset = autosize - aoffset;
+                                       q->to.type = D_REG;
+                                       q->to.reg = REGSP;
+
+                                       q->link = p->link;
+                                       p->link = q;
+                                       p = q;
+                               }
+                       }
 
+                       if(p->as != ARETURN) {
                                q = prg();
-                               q->as = AJMP;
                                q->line = p->line;
-                               q->to.type = D_OREG;
-                               q->to.offset = 0;
-                               q->to.reg = REGLINK;
-                               q->mark |= BRANCH;
-
                                q->link = p->link;
                                p->link = q;
-                               break;
+                               p = q;
                        }
-                       p->as = AMOVL;
-                       p->from.type = D_OREG;
-                       p->from.offset = 0;
-                       p->from.reg = REGSP;
-                       p->to.type = D_REG;
-                       p->to.reg = REGLINK;
 
-                       q = p;
-                       if(autosize)
-                               q = genIRR(p, AADDQ, autosize, NREG, REGSP);
-
-                       q1 = prg();
-                       q1->as = AJMP;
-                       q1->line = p->line;
-                       q1->to.type = D_OREG;
-                       q1->to.offset = 0;
-                       q1->to.reg = REGLINK;
-                       q1->mark |= BRANCH;
+                       p->as = ARET;
+                       p->line = p->line;
+                       p->to.type = D_OREG;
+                       p->to.offset = 0;
+                       p->to.reg = REGLINK;
 
-                       q1->link = q->link;
-                       q->link = q1;
                        break;
 
                become:
                        if(curtext->mark & LEAF) {
 
+                               if(!autosize) {
+                                       p->as = AB;
+                                       p->from = zprg.from;
+                                       break;
+                               }
+
+#ifdef optimise_time
                                q = prg();
                                q->line = p->line;
-                               q->as = AJMP;
+                               q->as = AB;
                                q->from = zprg.from;
                                q->to = p->to;
                                q->cond = p->cond;
                                q->link = p->link;
-                               q->mark |= BRANCH;
                                p->link = q;
 
-                               p->as = AADDQ;
+                               p->as = AADD;
                                p->from = zprg.from;
                                p->from.type = D_CONST;
                                p->from.offset = autosize;
@@ -293,318 +289,29 @@ noops(void)
                                p->to.reg = REGSP;
 
                                break;
+#endif
                        }
                        q = prg();
                        q->line = p->line;
-                       q->as = AJMP;
+                       q->as = AB;
                        q->from = zprg.from;
                        q->to = p->to;
                        q->cond = p->cond;
                        q->link = p->link;
-                       q->mark |= BRANCH;
                        p->link = q;
 
-                       q = genIRR(p, AADDQ, autosize, NREG, REGSP);
-
-                       p->as = AMOVL;
+                       p->as = AMOV;
                        p->from = zprg.from;
-                       p->from.type = D_OREG;
-                       p->from.offset = 0;
+                       p->from.type = D_XPRE;
+                       p->from.offset = -autosize;
                        p->from.reg = REGSP;
                        p->to = zprg.to;
                        p->to.type = D_REG;
                        p->to.reg = REGLINK;
 
                        break;
-                       
-
-               /* All I wanted was a MOVB... */
-               case AMOVB:
-               case AMOVW:
-                       /* rewrite sign extend; could use v3 extension in asmout case 1 */
-                       if (p->to.type == D_REG) {
-                               nocache(p);
-                               shift = (p->as == AMOVB) ? (64-8) : (64-16);
-                               if (p->from.type == D_REG) {
-                                       p->as = ASLLQ;
-                                       p->reg = p->from.reg;
-                                       p->from.type = D_CONST;
-                                       p->from.offset = shift;
-                                       q = genIRR(p, ASRAQ, shift, p->to.reg, p->to.reg);
-                                       break;
-                               }
-                               else {
-                                       p->as = (p->as == AMOVB) ? AMOVBU : AMOVWU;
-                                       q = genIRR(p, ASLLQ, shift, p->to.reg, p->to.reg);
-                                       q = genIRR(q, ASRAQ, shift, p->to.reg, p->to.reg);
-                               }
-                       }
-                       /* fall through... */
-               case AMOVBU:
-               case AMOVWU:
-                       if(!debug['x'])
-                               break;          /* use BWX extension */
-                       o = p->as;
-                       nocache(p);
-                       if (p->from.type == D_OREG) {
-                               if (p->to.type != D_REG)
-                                       break;
-                               p->as = AMOVQU;
-                               q = genXXX(p, AEXTBL, &p->to, REGTMP2, &p->to);
-                               if (o == AMOVW || o == AMOVWU)
-                                       q->as = AEXTWL;
-                               p->to.reg = REGTMP2;
-                               if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) {
-                                       q1 = genXXX(p, AMOVA, &p->from, NREG, &q->to);
-                                       q1->from.offset &= 7;
-                                       q->from = q->to;
-                               }
-                               else
-                                       q->from.reg = p->from.reg;
-                               if (o == AMOVB || o == AMOVW)
-                                       genXXX(q, o, &q->to, NREG, &q->to);
-                       }
-                       else if (p->to.type == D_OREG) {
-                               if (aclass(&p->from) == C_ZCON) {
-                                       p->from.type = D_REG;
-                                       p->from.reg = REGZERO;
-                               }
-                               else if (p->from.type != D_REG)
-                                       break;
-                               p->as = AMOVQU;
-                               q = genRRR(p, AMSKBL, p->to.reg, REGTMP2, REGTMP2);
-                               q1 = genRRR(q, AINSBL, p->to.reg, p->from.reg, REGTMP);
-                               if (o == AMOVW || o == AMOVWU) {
-                                       q->as = AMSKWL;
-                                       q1->as = AINSWL;
-                               }
-                               q2 = genXXX(q1, AOR, &q->to, REGTMP, &q->to);
-                               genXXX(q2, AMOVQU, &q->to, NREG, &p->to);
-                               p->from = p->to;
-                               p->to = q->to;
-                               if ((p->from.offset & 7) != 0 || aclass(&p->from) != C_SOREG) {
-                                       q->from.reg = REGTMP;
-                                       q1->from.reg = REGTMP;
-                                       q = genXXX(p, AMOVA, &p->from, NREG, &q->from);
-                                       q->from.offset &= 7;
-                               }
-                       }
-                       break;
-
-               case ASLLL:
-                       p->as = ASLLQ;
-                       p = genXXX(p, AADDL, &p->to, REGZERO, &p->to);
-                       break;
-
-               case ASRLL:
-                       if (p->to.type != D_REG) {
-                               diag("illegal dest type in %P", p);
-                               break;
-                       }
-                       if (p->reg == NREG)
-                               p->reg = p->to.reg;
-
-                       q = genXXX(p, ASRLQ, &p->from, REGTMP, &p->to);
-
-                       p->as = AZAP;
-                       p->from.type = D_CONST;
-                       p->from.offset = 0xf0;
-                       p->to.reg = REGTMP;
-                       p = q;
-
-                       p = genXXX(p, AADDL, &p->to, REGZERO, &p->to);
-                       break;
-
-               case ASRAL:
-                       p->as = ASRAQ;
-                       break;
-
-               case ADIVQ:
-               case ADIVQU:
-               case AMODQ:
-               case AMODQU:
-               case ADIVL:
-               case ADIVLU:
-               case AMODL:
-               case AMODLU:
-                       /* if (debug['d'])
-                               print("%P\n", p); */
-                       if(p->to.type != D_REG)
-                               break;
-                       /*if(debug['d'] && p->from.type == D_CONST) {
-                               q = genRRR(p, p->as, REGTMP, p->reg, p->to.reg);
-                               p->as = AMOVQ;
-                               p->reg = NREG;
-                               p->to.reg = REGTMP;
-                               p = q;
-                       }*/
-                       if(p->from.type == D_CONST) {
-                               if (p->reg == NREG)
-                                       p->reg = p->to.reg;
-                               switch (p->as) {
-                               case ADIVQ:
-                                       q = divconst(p, p->from.offset, p->reg, p->to.reg, 64);
-                                       break;
-                               case ADIVQU:
-                                       q = divuconst(p, p->from.offset, p->reg, p->to.reg, 64);
-                                       break;
-                               case AMODQ:
-                                       q = modconst(p, p->from.offset, p->reg, p->to.reg, 64);
-                                       break;
-                               case AMODQU:
-                                       q = divuconst(p, p->from.offset, p->reg, REGTMP2, 64);
-                                       q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2);
-                                       q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg);
-                                       break;
-                               case ADIVL:
-                                       q = divconst(p, p->from.offset, p->reg, p->to.reg, 32);
-                                       break;
-                               case ADIVLU:
-                                       q = divuconst(p, p->from.offset, p->reg, p->to.reg, 32);
-                                       break;
-                               case AMODL:
-                                       q = modconst(p, p->from.offset, p->reg, p->to.reg, 32);
-                                       break;
-                               case AMODLU:
-                                       q = divuconst(p, p->from.offset, p->reg, REGTMP2, 32);
-                                       q = genIRR(q, AMULQ, p->from.offset, REGTMP2, REGTMP2);
-                                       q = genRRR(q, ASUBQ, REGTMP2, p->reg, p->to.reg);
-                                       break;
-                               }
-                               excise(p);
-                               p = q;
-                               break;
-                       }
-                       if(p->from.type != D_REG){
-                               diag("bad instruction %P", p);
-                               break;
-                       }
-                       o = p->as;
-                       q = genIRR(p, ASUBQ, 16LL, NREG, REGSP);
-                       q = genstore(q, AMOVQ, p->from.reg, 8LL, REGSP);
-                       if (o == ADIVL || o == ADIVL || o == AMODL || o == AMODLU)
-                               q->as = AMOVL;
-
-                       q = genRRR(q, AMOVQ, p->reg, NREG, REGTMP);
-                       if (p->reg == NREG)
-                               q->from.reg = p->to.reg;
-
-                       /* CALL appropriate */
-                       q1 = prg();
-                       q1->link = q->link;
-                       q->link = q1;
-
-                       q1->as = AJSR;
-                       q1->line = p->line;
-                       q1->to.type = D_BRANCH;
-                       q1->cond = divsubr(o);
-                       q1->mark |= BRANCH;
-                       q = q1;
-
-                       q = genRRR(q, AMOVQ, REGTMP, NREG, p->to.reg);
-                       q = genIRR(q, AADDQ, 16LL, NREG, REGSP);
-                       excise(p);
-                       p = q;
-                       break;
-
-               /* Attempt to replace {cond. branch, mov} with a cmov */
-               /* XXX warning: this is all a bit experimental */
-               case ABEQ:
-               case ABNE:
-               case ABGE:
-               case ABGT:
-               case ABLE:
-               case ABLT:
-               case ABLBC:
-               case ABLBS:
-                       q = p->link;
-                       if (q == P)
-                               break;
-                       q1 = q->link;
-                       if (q1 != p->cond || q1 == P)
-                               break;
-/*print("%P\n", q); /* */
-                       if (q->to.type != D_REG)
-                               break;
-                       if (q->from.type != D_REG && (q->from.type != D_CONST || q->from.name != D_NONE))
-                               break;
-                       if (q->mark&LABEL2)
-                               break;
-/* print("%P\n", q); /* */
-                       if (q->as != AMOVQ)             /* XXX can handle more than this! */
-                               break;
-                       q->as = (p->as^1) + ACMOVEQ-ABEQ;       /* sleazy hack */
-                       q->reg = p->from.reg;           /* XXX check CMOVx operand order! */
-                       excise(p);              /* XXX p's LABEL? */
-                       if (!(q1->mark&LABEL2))
-                               q1->mark &= ~LABEL;
-                       break;
-               case AFBEQ:
-               case AFBNE:
-               case AFBGE:
-               case AFBGT:
-               case AFBLE:
-               case AFBLT:
-                       q = p->link;
-                       if (q == P)
-                               break;
-                       q1 = q->link;
-                       if (q1 != p->cond || q1 == P)
-                               break;
-                       if (q->from.type != D_FREG || q->to.type != D_FREG)
-                               break;
-/* print("%P\n", q); /* */
-                       if (q->mark&LABEL2)
-                               break;
-                       if (q->as != AMOVT)             /* XXX can handle more than this! */
-                               break;
-                       q->as = (p->as^1) + AFCMOVEQ-AFBEQ;     /* sleazy hack */
-                       q->reg = p->from.reg;           /* XXX check CMOVx operand order! */
-                       excise(p);              /* XXX p's LABEL? */
-                       if (!(q1->mark&LABEL2))
-                               q1->mark &= ~LABEL;
-                       break;
-               }
-       }
 
-       curtext = P;
-       q = P;          /* p - 1 */
-       q1 = firstp;    /* top of block */
-       o = 0;          /* count of instructions */
-       for(p = firstp; p != P; p = p1) {
-               p1 = p->link;
-               o++;
-               if(p->mark & NOSCHED){
-                       if(q1 != p){
-                               sched(q1, q);
-                       }
-                       for(; p != P; p = p->link){
-                               if(!(p->mark & NOSCHED))
-                                       break;
-                               q = p;
-                       }
-                       p1 = p;
-                       q1 = p;
-                       o = 0;
-                       continue;
-               }
-               if(p->mark & (LABEL|SYNC)) {
-                       if(q1 != p)
-                               sched(q1, q);
-                       q1 = p;
-                       o = 1;
                }
-               if(p->mark & (BRANCH|SYNC)) {
-                       sched(q1, p);
-                       q1 = p1;
-                       o = 0;
-               }
-               if(o >= NSCHED) {
-                       sched(q1, p);
-                       q1 = p1;
-                       o = 0;
-               }
-               q = p;
        }
 }
 
@@ -615,333 +322,3 @@ nocache(Prog *p)
        p->from.class = 0;
        p->to.class = 0;
 }
-
-/* XXX use of this may lose important LABEL flags, check that this isn't happening (or fix) */
-void
-excise(Prog *p)
-{
-       Prog *q;
-
-       q = p->link;
-       *p = *q;
-}
-
-void
-initdiv(void)
-{
-       Sym *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8;
-       Prog *p;
-
-       s1 = lookup("_divq", 0);
-       s2 = lookup("_divqu", 0);
-       s3 = lookup("_modq", 0);
-       s4 = lookup("_modqu", 0);
-       s5 = lookup("_divl", 0);
-       s6 = lookup("_divlu", 0);
-       s7 = lookup("_modl", 0);
-       s8 = lookup("_modlu", 0);
-       for(p = firstp; p != P; p = p->link)
-               if(p->as == ATEXT) {
-                       if(p->from.sym == s1)
-                               prog_divq = p;
-                       if(p->from.sym == s2)
-                               prog_divqu = p;
-                       if(p->from.sym == s3)
-                               prog_modq = p;
-                       if(p->from.sym == s4)
-                               prog_modqu = p;
-                       if(p->from.sym == s5)
-                               prog_divl = p;
-                       if(p->from.sym == s6)
-                               prog_divlu = p;
-                       if(p->from.sym == s7)
-                               prog_modl = p;
-                       if(p->from.sym == s8)
-                               prog_modlu = p;
-               }
-       if(prog_divq == P) {
-               diag("undefined: %s", s1->name);
-               prog_divq = curtext;
-       }
-       if(prog_divqu == P) {
-               diag("undefined: %s", s2->name);
-               prog_divqu = curtext;
-       }
-       if(prog_modq == P) {
-               diag("undefined: %s", s3->name);
-               prog_modq = curtext;
-       }
-       if(prog_modqu == P) {
-               diag("undefined: %s", s4->name);
-               prog_modqu = curtext;
-       }
-       if(prog_divl == P) {
-               diag("undefined: %s", s5->name);
-               prog_divl = curtext;
-       }
-       if(prog_divlu == P) {
-               diag("undefined: %s", s6->name);
-               prog_divlu = curtext;
-       }
-       if(prog_modl == P) {
-               diag("undefined: %s", s7->name);
-               prog_modl = curtext;
-       }
-       if(prog_modlu == P) {
-               diag("undefined: %s", s8->name);
-               prog_modlu = curtext;
-       }
-}
-
-Prog *
-divsubr(int o)
-{
-       switch(o) {
-       case ADIVQ:
-               return prog_divq;
-       case ADIVQU:
-               return prog_divqu;
-       case AMODQ:
-               return prog_modq;
-       case AMODQU:
-               return prog_modqu;
-       case ADIVL:
-               return prog_divl;
-       case ADIVLU:
-               return prog_divlu;
-       case AMODL:
-               return prog_modl;
-       case AMODLU:
-               return prog_modlu;
-       default:
-               diag("bad op %A in divsubr", o);
-               return prog_modlu;
-       }
-}
-
-Prog*
-divuconst(Prog *p, uvlong y, int num, int quot, int bits)
-{
-       int logy, i, shift;
-       uvlong k, m, n, mult, tmp, msb;
-
-       if(num == NREG)
-               num = quot;
-       if(y == 0) {
-               diag("division by zero");
-               return p;
-       }
-       if(y == 1)
-               return genRRR(p, AMOVQ, num, NREG, quot);
-
-       if(num == REGTMP || quot == REGTMP)
-               diag("bad register in divuconst");
-
-       tmp = y;
-       for(logy = -1; tmp != 0; logy++)
-               tmp >>= 1;
-
-       msb = (1LL << (bits-1));
-       if((y & (y-1)) == 0)            /* power of 2 */
-               return genIRR(p, ASRLQ, logy, num, quot);
-       if(y > msb)
-               return genIRR(p, ACMPUGE, y, num, quot);
-
-       /* k = (-2^(bits+logy)) % y */
-       m = msb/y;
-       n = msb%y;
-       if(debug['d'])
-               Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n",
-                       y, msb, m, n);
-       for(i = 0; i <= logy; i++) {
-               m *= 2LL;
-               n *= 2LL;
-               if(n > y) {
-                       m += 1LL;
-                       n -= y;
-               }
-       }
-       if(debug['d'])
-               Bprint(&bso, "divuconst: y=%lld msb=%lld m=%lld n=%lld\n",
-                       y, msb, m, n);
-       k = y - n;
-       if(k > (1LL << logy)) {
-               mult = 2LL*m + 1LL;
-               bits++;
-       } else
-               mult = m + 1LL;
-
-       shift = bits + logy;
-       if(debug['d'])
-               Bprint(&bso, "divuconst: y=%lld mult=%lld shift=%d bits=%d k=%lld\n",
-                       y, mult, shift, bits, k);
-       if(bits <= 32) {
-               p = genIRR(p, AMOVQ, mult, NREG, REGTMP);
-               p = genRRR(p, AEXTLL, REGZERO, num, quot);
-               p = genRRR(p, AMULQ, REGTMP, quot, quot);
-               p = genIRR(p, ASRLQ, shift, quot, quot);
-               p = genRRR(p, AADDL, quot, REGZERO, quot);
-               return p;
-       }
-       if(bits == 33) {
-               if(shift < 64) {
-                       mult <<= (64-shift);
-                       shift = 64;
-               }
-               p = genIRR(p, AMOVQ, mult, NREG, REGTMP);
-               p = genRRR(p, AEXTLL, REGZERO, num, quot);
-               p = genRRR(p, AUMULH, REGTMP, quot, quot);
-               if(shift != 64)
-                       p = genIRR(p, ASRLQ, shift-64, quot, quot);
-               p = genRRR(p, AADDL, quot, REGZERO, quot);
-               return p;
-       }
-       if(bits <= 64) {
-               if(shift < 64) {
-                       mult <<= (64-shift);
-                       shift = 64;
-               }
-               p = genIRR(p, AMOVQ, mult, NREG, REGTMP);
-               p = genRRR(p, AUMULH, REGTMP, num, quot);
-               if(shift != 64)
-                       p = genIRR(p, ASRLQ, shift-64, quot, quot);
-               return p;
-       }
-
-       p = genIRR(p, AMOVQ, mult, NREG, REGTMP);
-       p = genRRR(p, AUMULH, REGTMP, num, REGTMP);
-       p = genRRR(p, AADDQ, num, REGTMP, quot);
-       p = genRRR(p, ACMPUGT, REGTMP, quot, REGTMP);
-       p = genIRR(p, ASLLQ, 128-shift, REGTMP, REGTMP);
-       p = genIRR(p, ASRLQ, shift-64, quot, quot);
-       p = genRRR(p, AADDQ, REGTMP, quot, quot);
-       return p;
-}
-
-Prog *
-divconst(Prog *p, vlong y, int num, int quot, int bits)
-{
-       vlong yabs;
-       Prog *q;
-
-       yabs = y;
-       if (y < 0)
-               yabs = -y;
-       q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2);
-       if (num != quot)
-               q = genRRR(q, AMOVQ, num, NREG, quot);
-       q = genRRR(q, ACMOVGT, REGTMP2, REGTMP2, quot);
-       q = divuconst(q, yabs, quot, quot, bits-1);
-       q = genRRR(q, ASUBQ, quot, REGZERO, REGTMP);
-       q = genRRR(q, (y < 0)? ACMOVLT: ACMOVGT, REGTMP, REGTMP2, quot);
-       return q;
-}
-
-Prog *
-modconst(Prog *p, vlong y, int num, int quot, int bits)
-{
-       vlong yabs;
-       Prog *q;
-
-       yabs = y;
-       if (y < 0)
-               yabs = -y;
-       q = genRRR(p, ASUBQ, num, REGZERO, REGTMP2);
-       q = genRRR(q, ACMOVLT, num, REGTMP2, REGTMP2);
-       q = divuconst(q, yabs, REGTMP2, REGTMP2, bits-1);
-       q = genRRR(q, ASUBQ, REGTMP2, REGZERO, REGTMP);
-       q = genRRR(q, ACMOVLT, REGTMP, num, REGTMP2);
-       q = genIRR(q, AMULQ, yabs, REGTMP2, REGTMP2);
-       q = genRRR(q, ASUBQ, REGTMP2, num, quot);
-       return q;
-}
-
-Prog *
-genXXX(Prog *q, int op, Adr *from, int reg, Adr *to)
-{
-       Prog *p;
-
-       p = prg();
-       p->as = op;
-       p->line = q->line;
-       p->from = *from;
-       p->to = *to;
-       p->reg = reg;
-       p->link = q->link;
-       q->link = p;
-       return p;
-}
-
-Prog *
-genRRR(Prog *q, int op, int from, int reg, int to)
-{
-       Prog *p;
-
-       p = prg();
-       p->as = op;
-       p->line = q->line;
-       p->from.type = D_REG;
-       p->from.reg = from;
-       p->to.type = D_REG;
-       p->to.reg = to;
-       p->reg = reg;
-       p->link = q->link;
-       q->link = p;
-       return p;
-}
-
-Prog *
-genIRR(Prog *q, int op, vlong v, int reg, int to)
-{
-       Prog *p;
-
-       p = prg();
-       p->as = op;
-       p->line = q->line;
-       p->from.type = D_CONST;
-       p->from.offset = v;
-       p->to.type = D_REG;
-       p->to.reg = to;
-       p->reg = reg;
-       p->link = q->link;
-       q->link = p;
-       return p;
-}
-
-Prog *
-genstore(Prog *q, int op, int from, vlong offset, int to)
-{
-       Prog *p;
-
-       p = prg();
-       p->as = op;
-       p->line = q->line;
-       p->from.type = D_REG;
-       p->from.reg = from;
-       p->to.type = D_OREG;
-       p->to.reg = to;
-       p->to.offset = offset;
-       p->reg = NREG;
-       p->link = q->link;
-       q->link = p;
-       return p;
-}
-
-Prog *
-genload(Prog *q, int op, vlong offset, int from, int to)
-{
-       Prog *p;
-
-       p = prg();
-       p->as = op;
-       p->line = q->line;
-       p->from.type = D_OREG;
-       p->from.offset = offset;
-       p->from.reg = from;
-       p->to.type = D_REG;
-       p->to.reg = to;
-       p->reg = NREG;
-       p->link = q->link;
-       q->link = p;
-       return p;
-}