]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/7l/asm.c
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / 7l / asm.c
old mode 100755 (executable)
new mode 100644 (file)
index a92ab88..0cc5a27
@@ -1,54 +1,10 @@
 #include       "l.h"
 
-#define        LPUT(c)\
-       {\
-               cbp[0] = (c);\
-               cbp[1] = (c)>>8;\
-               cbp[2] = (c)>>16;\
-               cbp[3] = (c)>>24;\
-               cbp += 4;\
-               cbc -= 4;\
-               if(cbc <= 0)\
-                       cflush();\
-       }
+long   OFFSET;
 
-#define        CPUT(c)\
-       {\
-               cbp[0] = (c);\
-               cbp++;\
-               cbc--;\
-               if(cbc <= 0)\
-                       cflush();\
-       }
+#define PADDR(a)       ((a) & ~0xfffffffff0000000ull)
 
-#define        VLPUT(c)\
-       {\
-               cbp[0] = (c);\
-               cbp[1] = (c)>>8;\
-               cbp[2] = (c)>>16;\
-               cbp[3] = (c)>>24;\
-               cbp[4] = (c)>>32;\
-               cbp[5] = (c)>>40;\
-               cbp[6] = (c)>>48;\
-               cbp[7] = (c)>>56;\
-               cbp += 8;\
-               cbc -= 8;\
-               if(cbc <= 0)\
-                       cflush();\
-       }
-#define        LPUTBE(c)\
-       {\
-               cbp[0] = (c)>>24;\
-               cbp[1] = (c)>>16;\
-               cbp[2] = (c)>>8;\
-               cbp[3] = (c);\
-               cbp += 4;\
-               cbc -= 4;\
-               if(cbc <= 0)\
-                       cflush();\
-       }
-
-long
+vlong
 entryvalue(void)
 {
        char *a;
@@ -60,72 +16,105 @@ entryvalue(void)
        s = lookup(a, 0);
        if(s->type == 0)
                return INITTEXT;
-       if(s->type != STEXT && s->type != SLEAF)
+       switch(s->type) {
+       case STEXT:
+       case SLEAF:
+               break;
+       case SDATA:
+               if(dlm)
+                       return s->value+INITDAT;
+       default:
                diag("entry not text: %s", s->name);
+       }
        return s->value;
 }
 
+void
+cflush(void)
+{
+       int n;
+
+       n = sizeof(buf.cbuf) - cbc;
+       if(n)
+               write(cout, buf.cbuf, n);
+       cbp = buf.cbuf;
+       cbc = sizeof(buf.cbuf);
+}
+
 void
 asmb(void)
 {
        Prog *p;
-       vlong t;
+       long magic, t, etext;
+       vlong vl;
        Optab *o;
 
        if(debug['v'])
                Bprint(&bso, "%5.2f asm\n", cputime());
        Bflush(&bso);
-       seek(cout, HEADR, 0);
+       OFFSET = HEADR;
+       seek(cout, OFFSET, 0);
        pc = INITTEXT;
        for(p = firstp; p != P; p = p->link) {
                if(p->as == ATEXT) {
                        curtext = p;
-                       autosize = p->to.offset + 8;
+                       autosize = p->to.offset + PCSZ;
+               }
+               if(p->as == ADWORD && (pc & 7) != 0) {
+                       lputl(0);
+                       pc += 4;
                }
                if(p->pc != pc) {
-                       diag("phase error %lux sb %lux",
+                       diag("phase error %llux sb %llux",
                                p->pc, pc);
                        if(!debug['a'])
                                prasm(curp);
                        pc = p->pc;
                }
-               if (p->as == AMOVQ || p->as == AMOVT) {
-                       if ((p->from.reg == REGSP) && (p->from.offset&7) != 0
-                       || (p->to.reg == REGSP) && (p->to.offset&7) != 0)
-                               diag("bad stack alignment: %P", p);
-                       if ((p->from.reg == REGSB) && (p->from.offset&7) != 0
-                       || (p->to.reg == REGSB) && (p->to.offset&7) != 0)
-                               diag("bad global alignment: %P", p);
-               }
                curp = p;
                o = oplook(p);  /* could probably avoid this call */
-               if(asmout(p, o)) {
-                       p = p->link;
-                       pc += 4;
-               }
+               asmout(p, o);
                pc += o->size;
        }
+
        if(debug['a'])
                Bprint(&bso, "\n");
        Bflush(&bso);
        cflush();
 
+       /* output strings in text segment */
+       etext = INITTEXT + textsize;
+       for(t = pc; t < etext; t += sizeof(buf)-100) {
+               if(etext-t > sizeof(buf)-100)
+                       datblk(t, sizeof(buf)-100, 1);
+               else
+                       datblk(t, etext-t, 1);
+       }
+
        curtext = P;
        switch(HEADTYPE) {
        case 0:
-               seek(cout, rnd(HEADR+textsize, 8192), 0);
-               break;
-       case 1:
        case 2:
-       case 3:
-               seek(cout, HEADR+textsize, 0);
+       case 7:
+               OFFSET = HEADR+textsize;
+               seek(cout, OFFSET, 0);
+               break;
+       case 6: /* no header, padded segments */
+               OFFSET = rnd(HEADR+textsize, INITRND);
+               seek(cout, OFFSET, 0);
                break;
        }
+       if(dlm){
+               char buf[8];
+
+               write(cout, buf, INITDAT-textsize);
+               textsize = INITDAT;
+       }
        for(t = 0; t < datsize; t += sizeof(buf)-100) {
                if(datsize-t > sizeof(buf)-100)
-                       datblk(t, sizeof(buf)-100);
+                       datblk(t, sizeof(buf)-100, 0);
                else
-                       datblk(t, datsize-t);
+                       datblk(t, datsize-t, 0);
        }
 
        symsize = 0;
@@ -136,12 +125,17 @@ asmb(void)
                Bflush(&bso);
                switch(HEADTYPE) {
                case 0:
-                       seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
+                       debug['s'] = 1;
                        break;
                case 2:
-               case 1:
-               case 3:
-                       seek(cout, HEADR+textsize+datsize, 0);
+                       OFFSET = HEADR+textsize+datsize;
+                       seek(cout, OFFSET, 0);
+                       break;
+               case 6: /* no header, padded segments */
+                       OFFSET += rnd(datsize, INITRND);
+                       seek(cout, OFFSET, 0);
+                       break;
+               case 7:
                        break;
                }
                if(!debug['s'])
@@ -151,116 +145,119 @@ asmb(void)
                Bflush(&bso);
                if(!debug['s'])
                        asmlc();
+               if(dlm)
+                       asmdyn();
+               cflush();
+       }
+       else if(dlm){
+               seek(cout, HEADR+textsize+datsize, 0);
+               asmdyn();
                cflush();
        }
 
        if(debug['v'])
                Bprint(&bso, "%5.2f header\n", cputime());
        Bflush(&bso);
-       seek(cout, 0L, 0);
+       OFFSET = 0;
+       seek(cout, OFFSET, 0);
        switch(HEADTYPE) {
-       case 0:
-               lput(0x0183L);          /* magic and sections */
-               lput(0L);                       /* time and date */
-               vlput(rnd(HEADR+textsize, 8192)+datsize);
+       case 0: /* no header */
+       case 6: /* no header, padded segments */
+               break;
+       case 2: /* plan 9 */
+               magic = 4*28*28+7;
+               magic |= 0x00008000;            /* fat header */
+               if(dlm)
+                       magic |= 0x80000000;    /* dlm */
+               lput(magic);                    /* magic */
+               lput(textsize);                 /* sizes */
+               lput(datsize);
+               lput(bsssize);
                lput(symsize);                  /* nsyms */
-               lput(0x50L|(7L<<16));           /* size of optional hdr and flags */
-               lput(0413|(0x101L<<16));        /* magic and version */
-               lput(-1);                       /* pad for alignment */
-
-               vlput(rnd(HEADR+textsize, 8192));               /* sizes */
-               vlput(datsize);
-               vlput(bsssize);
-               vlput(entryvalue());            /* va of entry */
-               vlput(INITTEXT-HEADR);          /* va of base of text */
-               vlput(INITDAT);                 /* va of base of data */
-               vlput(INITDAT+datsize);         /* va of base of bss */
-               lput(~0L);                      /* gp reg mask */
-               /* dubious stuff starts here */
-               lput(0L);
-               lput(0L);
-               lput(0L);
+               vl = entryvalue();
+               lput(PADDR(vl));                /* va of entry */
                lput(0L);
-               lput(~0L);                      /* gp value ?? */
-               break;
-       case 1:
-               lput(0x0183L);          /* magic and sections */
-               lput(0L);                       /* time and date */
-               vlput(HEADR+textsize+datsize);
-               lput(symsize);                  /* nsyms */
-               lput(0x54L|(7L<<16));           /* size of optional hdr and flags */
-               lput(0407|(0x101L<<16));        /* magic and version */
-               lput(-1);                       /* pad for alignment */
-
-               vlput(textsize);                /* sizes */
-               vlput(datsize);
-               vlput(bsssize);
-               vlput(entryvalue());            /* va of entry */
-               vlput(INITTEXT);                /* va of base of text */
-               vlput(INITDAT);                 /* va of base of data */
-               vlput(INITDAT+datsize);         /* va of base of bss */
-               lput(~0L);                      /* gp reg mask */
-               /* dubious stuff starts here */
                lput(lcsize);
-               lput(0L);
-               lput(0L);
-               lput(0L);
-               lput(~0L);                      /* gp value ?? */
-               lput(0L);                       /* complete mystery */
-               break;
-       case 2:
-               lputbe(0x84b);                  /* magic */
-               lputbe(textsize);               /* sizes */
-               lputbe(datsize);
-               lputbe(bsssize);
-               lputbe(symsize);                /* nsyms */
-               lputbe(entryvalue());           /* va of entry */
-               lputbe(0L);
-               lputbe(lcsize);
-               break;
-       case 3:
-               /* ``headerless'' boot image -- magic no is a branch */
-               lput(0xc3e00007);               /* magic (branch) */
-               lputbe(textsize);               /* sizes */
-               lputbe(datsize);
-               lputbe(bsssize);
-               lputbe(symsize);                /* nsyms */
-               lputbe(entryvalue());           /* va of entry */
-               lputbe(0L);
-               lputbe(lcsize);
+               llput(vl);                      /* va of entry */
                break;
        }
        cflush();
 }
 
 void
-lput(long l)
+cput(int c)
+{
+       cbp[0] = c;
+       cbp++;
+       cbc--;
+       if(cbc <= 0)
+               cflush();
+}
+
+void
+wput(long l)
 {
-       LPUT(l);
+
+       cbp[0] = l>>8;
+       cbp[1] = l;
+       cbp += 2;
+       cbc -= 2;
+       if(cbc <= 0)
+               cflush();
 }
 
 void
-lputbe(long l)
+wputl(long l)
 {
-       LPUTBE(l);
+
+       cbp[0] = l;
+       cbp[1] = l>>8;
+       cbp += 2;
+       cbc -= 2;
+       if(cbc <= 0)
+               cflush();
 }
 
 void
-vlput(vlong l)
+lput(long l)
 {
-       VLPUT(l);
+
+       cbp[0] = l>>24;
+       cbp[1] = l>>16;
+       cbp[2] = l>>8;
+       cbp[3] = l;
+       cbp += 4;
+       cbc -= 4;
+       if(cbc <= 0)
+               cflush();
 }
 
 void
-cflush(void)
+lputl(long l)
 {
-       int n;
 
-       n = sizeof(buf.cbuf) - cbc;
-       if(n)
-               write(cout, buf.cbuf, n);
-       cbp = buf.cbuf;
-       cbc = sizeof(buf.cbuf);
+       cbp[3] = l>>24;
+       cbp[2] = l>>16;
+       cbp[1] = l>>8;
+       cbp[0] = l;
+       cbp += 4;
+       cbc -= 4;
+       if(cbc <= 0)
+               cflush();
+}
+
+void
+llput(vlong v)
+{
+       lput(v>>32);
+       lput(v);
+}
+
+void
+llputl(vlong v)
+{
+       lputl(v);
+       lputl(v>>32);
 }
 
 void
@@ -290,6 +287,10 @@ asmsym(void)
                                putsymb(s->name, 'B', s->value+INITDAT, s->version);
                                continue;
 
+                       case SSTRING:
+                               putsymb(s->name, 'T', s->value, s->version);
+                               continue;
+
                        case SFILE:
                                putsymb(s->name, 'f', s->value, s->version);
                                continue;
@@ -303,10 +304,10 @@ asmsym(void)
                /* filenames first */
                for(a=p->to.autom; a; a=a->link)
                        if(a->type == D_FILE)
-                               putsymb(a->sym->name, 'z', a->offset, 0);
+                               putsymb(a->asym->name, 'z', a->aoffset, 0);
                        else
                        if(a->type == D_FILE1)
-                               putsymb(a->sym->name, 'Z', a->offset, 0);
+                               putsymb(a->asym->name, 'Z', a->aoffset, 0);
 
                if(s->type == STEXT)
                        putsymb(s->name, 'T', s->value, s->version);
@@ -314,13 +315,13 @@ asmsym(void)
                        putsymb(s->name, 'L', s->value, s->version);
 
                /* frame, auto and param after */
-               putsymb(".frame", 'm', p->to.offset+8, 0);
+               putsymb(".frame", 'm', p->to.offset+PCSZ, 0);
                for(a=p->to.autom; a; a=a->link)
                        if(a->type == D_AUTO)
-                               putsymb(a->sym->name, 'a', -a->offset, 0);
+                               putsymb(a->asym->name, 'a', -a->aoffset, 0);
                        else
                        if(a->type == D_PARAM)
-                               putsymb(a->sym->name, 'p', a->offset, 0);
+                               putsymb(a->asym->name, 'p', a->aoffset, 0);
        }
        if(debug['v'] || debug['n'])
                Bprint(&bso, "symsize = %lud\n", symsize);
@@ -328,37 +329,46 @@ asmsym(void)
 }
 
 void
-putsymb(char *s, int t, long v, int ver)
+putsymb(char *s, int t, vlong v, int ver)
 {
-       int i, f;
+       int i, f, l;
 
        if(t == 'f')
                s++;
-       LPUTBE(v);
+       l = 4;
+       switch(HEADTYPE){
+       default:
+               break;
+       case 2:
+               lput(v>>32);
+               l = 8;
+               break;
+       }
+       lput(v);
        if(ver)
                t += 'a' - 'A';
-       CPUT(t+0x80);                   /* 0x80 is variable length */
+       cput(t+0x80);                   /* 0x80 is variable length */
 
        if(t == 'Z' || t == 'z') {
-               CPUT(s[0]);
+               cput(s[0]);
                for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
-                       CPUT(s[i]);
-                       CPUT(s[i+1]);
+                       cput(s[i]);
+                       cput(s[i+1]);
                }
-               CPUT(0);
-               CPUT(0);
+               cput(0);
+               cput(0);
                i++;
        }
        else {
                for(i=0; s[i]; i++)
-                       CPUT(s[i]);
-               CPUT(0);
+                       cput(s[i]);
+               cput(0);
        }
-       symsize += 4 + 1 + i + 1;
+       symsize += l + 1 + i + 1;
 
        if(debug['n']) {
                if(t == 'z' || t == 'Z') {
-                       Bprint(&bso, "%c %.8lux ", t, v);
+                       Bprint(&bso, "%c %.8llux ", t, v);
                        for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
                                f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
                                Bprint(&bso, "/%x", f);
@@ -367,9 +377,9 @@ putsymb(char *s, int t, long v, int ver)
                        return;
                }
                if(ver)
-                       Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
+                       Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver);
                else
-                       Bprint(&bso, "%c %.8lux %s\n", t, v, s);
+                       Bprint(&bso, "%c %.8llux %s\n", t, v, s);
        }
 }
 
@@ -387,20 +397,20 @@ asmlc(void)
                if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
                        if(p->as == ATEXT)
                                curtext = p;
-                       if(debug['L'])
-                               Bprint(&bso, "%6lux %P\n",
+                       if(debug['V'])
+                               Bprint(&bso, "%6llux %P\n",
                                        p->pc, p);
                        continue;
                }
-               if(debug['L'])
+               if(debug['V'])
                        Bprint(&bso, "\t\t%6ld", lcsize);
                v = (p->pc - oldpc) / MINLC;
                while(v) {
                        s = 127;
                        if(v < 127)
                                s = v;
-                       CPUT(s+128);    /* 129-255 +pc */
-                       if(debug['L'])
+                       cput(s+128);    /* 129-255 +pc */
+                       if(debug['V'])
                                Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
                        v -= s;
                        lcsize++;
@@ -409,36 +419,36 @@ asmlc(void)
                oldlc = p->line;
                oldpc = p->pc + MINLC;
                if(s > 64 || s < -64) {
-                       CPUT(0);        /* 0 vv +lc */
-                       CPUT(s>>24);
-                       CPUT(s>>16);
-                       CPUT(s>>8);
-                       CPUT(s);
-                       if(debug['L']) {
+                       cput(0);        /* 0 vv +lc */
+                       cput(s>>24);
+                       cput(s>>16);
+                       cput(s>>8);
+                       cput(s);
+                       if(debug['V']) {
                                if(s > 0)
                                        Bprint(&bso, " lc+%ld(%d,%ld)\n",
                                                s, 0, s);
                                else
                                        Bprint(&bso, " lc%ld(%d,%ld)\n",
                                                s, 0, s);
-                               Bprint(&bso, "%6lux %P\n",
+                               Bprint(&bso, "%6llux %P\n",
                                        p->pc, p);
                        }
                        lcsize += 5;
                        continue;
                }
                if(s > 0) {
-                       CPUT(0+s);      /* 1-64 +lc */
-                       if(debug['L']) {
+                       cput(0+s);      /* 1-64 +lc */
+                       if(debug['V']) {
                                Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
-                               Bprint(&bso, "%6lux %P\n",
+                               Bprint(&bso, "%6llux %P\n",
                                        p->pc, p);
                        }
                } else {
-                       CPUT(64-s);     /* 65-128 -lc */
-                       if(debug['L']) {
+                       cput(64-s);     /* 65-128 -lc */
+                       if(debug['V']) {
                                Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
-                               Bprint(&bso, "%6lux %P\n",
+                               Bprint(&bso, "%6llux %P\n",
                                        p->pc, p);
                        }
                }
@@ -446,26 +456,31 @@ asmlc(void)
        }
        while(lcsize & 1) {
                s = 129;
-               CPUT(s);
+               cput(s);
                lcsize++;
        }
-       if(debug['v'] || debug['L'])
+       if(debug['v'] || debug['V'])
                Bprint(&bso, "lcsize = %ld\n", lcsize);
        Bflush(&bso);
 }
 
 void
-datblk(long s, long n)
+datblk(long s, long n, int str)
 {
+       Sym *v;
        Prog *p;
        char *cast;
-       long l, fl, j, d;
+       long a, l, fl, j;
+       vlong d;
        int i, c;
 
        memset(buf.dbuf, 0, n+100);
        for(p = datap; p != P; p = p->link) {
+               if(str != (p->from.sym->type == SSTRING))
+                       continue;
                curp = p;
-               l = p->from.sym->value + p->from.offset - s;
+               a = p->from.sym->value + p->from.offset;
+               l = a - s;
                c = p->reg;
                i = 0;
                if(l < 0) {
@@ -488,7 +503,7 @@ datblk(long s, long n)
                }
                switch(p->to.type) {
                default:
-                       diag("unknown mode in initialization\n%P", p);
+                       diag("unknown mode in initialization%P", p);
                        break;
 
                case D_FCONST:
@@ -498,7 +513,7 @@ datblk(long s, long n)
                                fl = ieeedtof(p->to.ieee);
                                cast = (char*)&fl;
                                for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[fnuxi8[i]];
+                                       buf.dbuf[l] = cast[fnuxi4[i]];
                                        l++;
                                }
                                break;
@@ -521,19 +536,27 @@ datblk(long s, long n)
 
                case D_CONST:
                        d = p->to.offset;
-                       if(p->to.sym) {
-                               if(p->to.sym->type == STEXT ||
-                                  p->to.sym->type == SLEAF)
+                       v = p->to.sym;
+                       if(v) {
+                               switch(v->type) {
+                               case SUNDEF:
+                                       ckoff(v, d);
+                               case STEXT:
+                               case SLEAF:
+                               case SSTRING:
                                        d += p->to.sym->value;
-                               if(p->to.sym->type == SDATA)
-                                       d += p->to.sym->value + INITDAT;
-                               if(p->to.sym->type == SBSS)
+                                       break;
+                               case SDATA:
+                               case SBSS:
                                        d += p->to.sym->value + INITDAT;
+                               }
+                               if(dlm)
+                                       dynreloc(v, a+INITDAT, 1);
                        }
                        cast = (char*)&d;
                        switch(c) {
                        default:
-                               diag("bad nuxi %d %d\n%P", c, i, curp);
+                               diag("bad nuxi %d %d%P", c, i, curp);
                                break;
                        case 1:
                                for(; i<c; i++) {
@@ -554,13 +577,8 @@ datblk(long s, long n)
                                }
                                break;
                        case 8:
-                               for(; i<4; i++) {
-                                       buf.dbuf[l] = cast[inuxi4[i]];
-                                       l++;
-                               }
-                               d = p->to.offset >> 32;
                                for(; i<c; i++) {
-                                       buf.dbuf[l] = cast[inuxi4[i-4]];
+                                       buf.dbuf[l] = cast[inuxi8[i]];
                                        l++;
                                }
                                break;
@@ -571,650 +589,27 @@ datblk(long s, long n)
        write(cout, buf.dbuf, n);
 }
 
-#define        OP_RRR(op,r1,r2,r3)\
-       (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((r3)&31L))
-#define        OP_IRR(op,i,r2,r3)\
-       (op|(((i)&255L)<<13)|0x1000|(((r2)&31L)<<21)|((r3)&31L))
-#define        OP_MEM(op,d,r1,r2)\
-       (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((d)&0xffff))
-#define OP_BR(op,d,r1)\
-       (op|((d)&0x1fffff)|(((r1)&31L)<<21))
+static Ieee chipfloats[] = {
+       {0x00000000, 0x00000000}, /* 0 */
+       {0x00000000, 0x3ff00000}, /* 1 */
+       {0x00000000, 0x40000000}, /* 2 */
+       {0x00000000, 0x40080000}, /* 3 */
+       {0x00000000, 0x40100000}, /* 4 */
+       {0x00000000, 0x40140000}, /* 5 */
+       {0x00000000, 0x3fe00000}, /* .5 */
+       {0x00000000, 0x40240000}, /* 10 */
+};
 
 int
-asmout(Prog *p, Optab *o)
-{
-       long o1, o2, o3, o4, o5, o6;
-       vlong v;
-       int r, a;
-
-       o1 = 0;
-       o2 = 0;
-       o3 = 0;
-       o4 = 0;
-       o5 = 0;
-       o6 = 0;
-       switch(o->type) {
-       default:
-               diag("unknown type %d", o->type);
-               if(!debug['a'])
-                       prasm(p);
-               break;
-
-       case 0:         /* pseudo ops */
-               break;
-
-       case 1:         /* register-register moves */
-               if(p->as == AMOVB || p->as == AMOVW)            /* noop should rewrite */
-                       diag("forbidden SEX: %P", p);
-               if(p->as == AMOVBU || p->as == AMOVWU) {
-                       v = 1;
-                       if (p->as == AMOVWU)
-                               v = 3;
-                       o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);
-               }
-               else {
-                       a = AOR;
-                       if(p->as == AMOVL)
-                               a = AADDL;
-                       if(p->as == AMOVLU)
-                               a = AEXTLL;
-                       o1 = OP_RRR(opcode(a), REGZERO, p->from.reg, p->to.reg);
-               }
-               break;
-
-       case 2:         /* <operate> r1,[r2],r3 */
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
-               break;
-
-       case 3:         /* <operate> $n,[r2],r3 */
-               v = regoff(&p->from);
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
-               break;
-
-       case 4:         /* beq r1,sbra */
-               if(p->cond == P)
-                       v = -4 >> 2;
-               else
-                       v = (p->cond->pc - pc-4) >> 2;
-               o1 = OP_BR(opcode(p->as), v, p->from.reg);
-               break;
-
-       case 5:         /* jmp [r1],0(r2) */
-               r = p->reg;
-               a = p->as;
-               if(r == NREG) {
-                       r = o->param;
-/*                     if(a == AJMP && p->to.reg == REGLINK)
-                               a = ARET; /* this breaks the kernel -- maybe we need to clear prediction stack on each context switch... */
-               }
-               o1 = OP_MEM(opcode(a), 0, p->to.reg, r);
-               break;
-
-       case 6:         /* movq $n,r1 and movq $soreg,r1 */
-               r = p->from.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->from);
-               o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);
-               break;
-
-       case 7:         /* movbu r1, r2 */
-               v = 1;
-               if (p->as == AMOVWU)
-                       v = 3;
-               o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);
-               break;
-
-       case 8:         /* mov r, soreg ==> stq o(r) */
-               r = p->to.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->to);
-               if (p->as == AMOVQ || p->as == AMOVT)
-                       if ((r == REGSP || r == REGSB) && (v&7) != 0)
-                               diag("bad alignment: %P", p);
-               o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);
-               break;
-
-       case 9:         /* mov soreg, r ==> ldq o(r) */
-               r = p->from.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->from);
-               if (p->as == AMOVQ || p->as == AMOVT)
-                       if ((r == REGSP || r == REGSB) && (v&7) != 0)
-                               diag("bad alignment: %P", p);
-               o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);
-               break;
-
-       case 10:        /* movb r1,r2 */
-               v = 64 - 8;
-               if (p->as == AMOVW)
-                       v = 64 - 16;
-               o1 = OP_IRR(opcode(ASLLQ), v, p->from.reg, p->to.reg);
-               o2 = OP_IRR(opcode(ASRAQ), v, p->to.reg, p->to.reg);
-               break;
-
-       case 11:        /* jmp lbra */
-               if(p->cond == P)
-                       v = -4 >> 2;
-               else
-                       v = (p->cond->pc - pc-4) >> 2;
-               a = ABR;
-               r = REGZERO;
-               if (p->as == AJSR) {
-                       a = ABSR;
-                       r = REGLINK;
-               }
-               o1 = OP_BR(opcode(a), v, r);
-               break;
-
-       case 12:        /* addq $n,[r2],r3 ==> lda */
-               v = regoff(&p->from);
-               if (p->as == ASUBQ)
-                       v = -v;
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);
-               break;
-
-       case 13:        /* <op> $scon,[r2],r3 */
-               v = regoff(&p->from);
-               if(p->to.reg == REGTMP || p->reg == REGTMP)
-                       diag("cant synthesize large constant\n%P", p);
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);
-               o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
-               break;
-
-       case 14:        /* <op> $lcon,[r2],r3 */
-               v = regoff(&p->from);
-               if(v & 0x8000)
-                       v += 0x10000;
-               if(p->to.reg == REGTMP || p->reg == REGTMP)
-                       diag("cant synthesize large constant\n%P", p);
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
-               o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
-               break;
-
-       case 15:        /* mov $lcon,r1 */
-               v = regoff(&p->from);
-               if(v & 0x8000)
-                       v += 0x10000;
-               o1 = OP_MEM(opcode(AMOVA), v, o->param, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);
-               break;
-
-       case 16:        /* mov $qcon,r1 */
-               v = regoff(&p->from);
-               if(v & 0x8000)
-                       v += 0x10000;
-               if((v>>31)&1)
-                       v += (1LL<<32);
-               if((v>>47)&1)
-                       v += (1LL<<48);
-               o1 = OP_MEM(opcode(AMOVA), v>>32, o->param, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
-               o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
-               o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);
-               o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);
-               break;
-
-       case 17:        /* mov f1,f2 ==> fcpys f1,f1,f2 */
-               o1 = OP_RRR(opcode(ACPYS), p->from.reg, p->from.reg, p->to.reg);
-               break;
-
-       case 18:        /* call_pal imm */
-               v = regoff(&p->from);
-               o1 = OP_MEM(opcode(ACALL_PAL), v, 0, 0);
-               break;
-
-       case 19:        /* mov r, loreg ==> ldah,stq */
-               r = p->to.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->to);
-               if (p->as == AMOVQ || p->as == AMOVT)
-                       if ((r == REGSP || r == REGSB) && (v&7) != 0)
-                               diag("bad alignment: %P", p);
-               if(v & 0x8000)
-                       v += 0x10000;
-               o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);
-               o2 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);
-               break;
-
-       case 20:        /* mov loreg, r ==> ldah,ldq */
-               r = p->from.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->from);
-               if (p->as == AMOVQ || p->as == AMOVT)
-                       if ((r == REGSP || r == REGSB) && (v&7) != 0)
-                               diag("bad alignment: %P", p);
-               if(v & 0x8000)
-                       v += 0x10000;
-               o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);
-               o2 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);
-               break;
-
-#ifdef NEVER
-       case 21:        /* mov r1,$qoreg */
-               r = p->to.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->to);
-               if(v & 0x8000)
-                       v += 0x10000;
-               if((v>>31)&1)
-                       v += (1LL<<32);
-               if((v>>47)&1)
-                       v += (1LL<<48);
-               o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
-               o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
-               o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
-               o5 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);
-               break;
-
-       case 22:        /* mov $qoreg,r1 */
-               r = p->from.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->from);
-               if(v & 0x8000)
-                       v += 0x10000;
-               if((v>>31)&1)
-                       v += (1LL<<32);
-               if((v>>47)&1)
-                       v += (1LL<<48);
-               o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
-               o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
-               o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
-               o5 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);
-               break;
-#endif
-
-       case 23:        /* <op> $qcon,r1 */
-               if(p->to.reg == REGTMP || p->reg == REGTMP)
-                       diag("cant synthesize large constant\n%P", p);
-               v = regoff(&p->from);
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               if(v & 0x8000)
-                       v += 0x10000;
-               if((v>>31)&1)
-                       v += (1LL<<32);
-               if((v>>47)&1)
-                       v += (1LL<<48);
-               o1 = OP_MEM(opcode(AMOVA), v>>32, REGZERO, REGTMP);
-               o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
-               o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
-               o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);
-               o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
-               o6 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
-               break;
-
-       case 24:        /* movq Fn, FPCR */
-               r = p->from.reg;
-               o1 = OP_RRR(opcode(AADDT+AEND), r, r, r);
-               break;
-
-       case 25:        /* movq FPCR, Fn */
-               r = p->to.reg;
-               o1 = OP_RRR(opcode(AADDS+AEND), r, r, r);
-               break;
-
-       case 26:        /* movq Rn, C_PREG */
-               r = p->from.reg;
-               o1 = OP_RRR(opcode(ASUBQ+AEND), r, r, 0) | p->to.reg & 255;
-               break;
-
-       case 27:        /* movq C_PREG, Rn */
-               r = p->to.reg;
-               o1 = OP_RRR(opcode(AADDQ+AEND), r, r, 0) | p->from.reg & 255;
-               break;
-
-       case 28:        /* cvttq r1,r3 */
-               r = p->from.reg;
-               o1 = OP_RRR(opcode(p->as), r, REGZERO, p->to.reg);
-               break;
-
-       case 29:        /* movq pcc, rpcc -> Rn */
-               o1 = OP_MEM(opcode(ARPCC), 0, REGZERO, p->to.reg);
-               break;
-
-       case 30:        /* rei/mb/trapb */
-               o1 = OP_MEM(opcode(p->as), 0, REGZERO, REGZERO);
-               break;
-
-       case 31:        /* fetch (Rn) */
-               o1 = OP_MEM(opcode(p->as), 0, REGZERO, p->from.reg);
-               break;
-
-       case 32:        /* movqp r, soreg ==> stqp o(r) */
-               r = p->to.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->to);
-               if (v < -0x800 || v >= 0x800)
-                       diag("physical store out of range\n%P", p);
-               v &= 0xfff;
-               o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);
-               break;
-
-       case 33:        /* movqp soreg, r ==> ldqp o(r) */
-               r = p->from.reg;
-               if(r == NREG)
-                       r = o->param;
-               v = regoff(&p->from);
-               if (v < -0x800 || v >= 0x800)
-                       diag("physical load out of range\n%P", p);
-               v &= 0xfff;
-               o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);
-               break;
-
-       case 34:        /* <operate> $-n,[r2],r3 */
-               v = regoff(&p->from);
-               r = p->reg;
-               if(r == NREG)
-                       r = p->to.reg;
-               switch (a = p->as) {
-               case AAND:
-                       a = AANDNOT;
-                       break;
-               case AANDNOT:
-                       a = AAND;
-                       break;
-               case AOR:
-                       a = AORNOT;
-                       break;
-               case AORNOT:
-                       a = AOR;
-                       break;
-               case AXOR:
-                       a = AXORNOT;
-                       break;
-               case AXORNOT:
-                       a = AXOR;
-                       break;
-               default:
-                       diag("bad in NCON case: %P", p);
-               }
-               v = ~v;
-               o1 = OP_IRR(opcode(a), v, r, p->to.reg);
-               break;
-
-       case 40:        /* word */
-               o1 = regoff(&p->to);
-               break;
-
-       }
-       switch(o->size) {
-       default:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux:\t\t%P\n", p->pc, p);
-               break;
-       case 4:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux\t%P\n", p->pc, o1, p);
-               LPUT(o1);
-               break;
-       case 8:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %P\n", p->pc, o1, o2, p);
-               LPUT(o1);
-               LPUT(o2);
-               break;
-       case 12:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %P\n", p->pc, o1, o2, o3, p);
-               LPUT(o1);
-               LPUT(o2);
-               LPUT(o3);
-               break;
-       case 16:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %P\n",
-                               p->pc, o1, o2, o3, o4, p);
-               LPUT(o1);
-               LPUT(o2);
-               LPUT(o3);
-               LPUT(o4);
-               break;
-       case 20:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",
-                               p->pc, o1, o2, o3, o4, o5, p);
-               LPUT(o1);
-               LPUT(o2);
-               LPUT(o3);
-               LPUT(o4);
-               LPUT(o5);
-               break;
-       case 24:
-               if(debug['a'])
-                       Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",
-                               p->pc, o1, o2, o3, o4, o5, o6, p);
-               LPUT(o1);
-               LPUT(o2);
-               LPUT(o3);
-               LPUT(o4);
-               LPUT(o5);
-               LPUT(o6);
-               break;
-       }
-       return 0;
-}
-
-#define        OP(x,y) (((x)<<26)|((y)<<5))
-#define        FP(x)   OP(22, (x)|0xc0)        /* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */
-#define        FP2(x)  OP(22, (x) /*|0x080*/)  /* note: this sets round/trap modes (chopped, software?). used for cvtxx? */
-#define        FP3(x)  OP(22, (x)|0x080)       /* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */
-
-long
-opcode(int a)
+chipfloat(Ieee *e)
 {
-       switch (a) {
-       /* loads */
-       case AMOVB:             /* misnomer; pretend it's ok for now */
-diag("opcode(AMOVB)");
-       case AMOVBU:            return OP(10, 0);       /* v 3 */
-       case AMOVW:             /* misnomer; pretend it's ok for now */
-diag("opcode(AMOVW)");
-       case AMOVWU:            return OP(12, 0);       /* v 3 */
-       case AMOVL:             return OP(40, 0);
-       case AMOVQ:             return OP(41, 0);
-       case AMOVQU:            return OP(11, 0);
-       case AMOVS:             return OP(34, 0);
-       case AMOVT:             return OP(35, 0);
-
-       /* stores */
-       case AMOVB+AEND:                /* misnomer; pretend it's ok for now */
-       case AMOVBU+AEND:       return OP(14, 0);       /* v 3 */
-       case AMOVW+AEND:        /* misnomer; pretend it's ok for now */
-       case AMOVWU+AEND:       return OP(13, 0);       /* v 3 */
-       case AMOVL+AEND:        return OP(44, 0);
-       case AMOVQ+AEND:        return OP(45, 0);
-       case AMOVQU+AEND:       return OP(15, 0);
-       case AMOVS+AEND:        return OP(38, 0);
-       case AMOVT+AEND:        return OP(39, 0);
-
-       /* physical */
-       case AMOVLP+AEND:       return OP(31, 0)|0x8000;
-       case AMOVQP+AEND:       return OP(31, 0)|0x9000;
-       case AMOVLP:            return OP(27, 0)|0x8000;
-       case AMOVQP:            return OP(27, 0)|0x9000;
-
-       /* load address */
-       case AMOVA:             return OP(8, 0);
-       case AMOVAH:            return OP(9, 0);
-
-       /* locking */
-       case AMOVLL:            return OP(42, 0);       /* load locked */
-       case AMOVQL:            return OP(43, 0);       /* load locked */
-       case AMOVLC+AEND:       return OP(46, 0);       /* store cond */
-       case AMOVQC+AEND:       return OP(47, 0);       /* store cond */
-
-       case AADDL:             return OP(16, 0);
-       case AADDLV:            return OP(16, 64);
-       case AADDQ:             return OP(16, 32);
-       case AADDQV:            return OP(16, 96);
-       case AS4ADDL:           return OP(16, 2);
-       case AS4ADDQ:           return OP(16, 34);
-       case AS8ADDL:           return OP(16, 18);
-       case AS8ADDQ:           return OP(16, 50);
-       case AS4SUBL:           return OP(16, 11);
-       case AS4SUBQ:           return OP(16, 43);
-       case AS8SUBL:           return OP(16, 27);
-       case AS8SUBQ:           return OP(16, 59);
-       case ASUBL:             return OP(16, 9);
-       case ASUBLV:            return OP(16, 73);
-       case ASUBQ:             return OP(16, 41);
-       case ASUBQV:            return OP(16, 105);
-       case ACMPEQ:            return OP(16, 45);
-       case ACMPGT:            return OP(16, 77);
-       case ACMPGE:            return OP(16, 109);
-       case ACMPUGT:           return OP(16, 29);
-       case ACMPUGE:           return OP(16, 61);
-       case ACMPBLE:           return OP(16, 15);
-
-       case AAND:              return OP(17, 0);
-       case AANDNOT:           return OP(17, 8);
-       case AOR:               return OP(17, 32);
-       case AORNOT:            return OP(17, 40);
-       case AXOR:              return OP(17, 64);
-       case AXORNOT:           return OP(17, 72);
-
-       case ACMOVEQ:           return OP(17, 36);
-       case ACMOVNE:           return OP(17, 38);
-       case ACMOVLT:           return OP(17, 68);
-       case ACMOVGE:           return OP(17, 70);
-       case ACMOVLE:           return OP(17, 100);
-       case ACMOVGT:           return OP(17, 102);
-       case ACMOVLBS:          return OP(17, 20);
-       case ACMOVLBC:          return OP(17, 22);
-
-       case AMULL:             return OP(19, 0);
-       case AMULQ:             return OP(19, 32);
-       case AMULLV:            return OP(19, 64);
-       case AMULQV:            return OP(19, 96);
-       case AUMULH:            return OP(19, 48);
-
-       case ASLLQ:             return OP(18, 57);
-       case ASRLQ:             return OP(18, 52);
-       case ASRAQ:             return OP(18, 60);
-
-       case AEXTBL:            return OP(18, 6);
-       case AEXTWL:            return OP(18, 22);
-       case AEXTLL:            return OP(18, 38);
-       case AEXTQL:            return OP(18, 54);
-       case AEXTWH:            return OP(18, 90);
-       case AEXTLH:            return OP(18, 106);
-       case AEXTQH:            return OP(18, 122);
-
-       case AINSBL:            return OP(18, 11);
-       case AINSWL:            return OP(18, 27);
-       case AINSLL:            return OP(18, 43);
-       case AINSQL:            return OP(18, 59);
-       case AINSWH:            return OP(18, 87);
-       case AINSLH:            return OP(18, 103);
-       case AINSQH:            return OP(18, 119);
-
-       case AMSKBL:            return OP(18, 2);
-       case AMSKWL:            return OP(18, 18);
-       case AMSKLL:            return OP(18, 34);
-       case AMSKQL:            return OP(18, 50);
-       case AMSKWH:            return OP(18, 82);
-       case AMSKLH:            return OP(18, 98);
-       case AMSKQH:            return OP(18, 114);
-
-       case AZAP:              return OP(18, 48);
-       case AZAPNOT:           return OP(18, 49);
-
-       case AJMP:              return OP(26, 0);
-       case AJSR:              return OP(26, 512);
-       case ARET:              return OP(26, 1024);
-
-       case ABR:               return OP(48, 0);
-       case ABSR:              return OP(52, 0);
-
-       case ABEQ:              return OP(57, 0);
-       case ABNE:              return OP(61, 0);
-       case ABLT:              return OP(58, 0);
-       case ABGE:              return OP(62, 0);
-       case ABLE:              return OP(59, 0);
-       case ABGT:              return OP(63, 0);
-       case ABLBC:             return OP(56, 0);
-       case ABLBS:             return OP(60, 0);
-
-       case AFBEQ:             return OP(49, 0);
-       case AFBNE:             return OP(53, 0);
-       case AFBLT:             return OP(50, 0);
-       case AFBGE:             return OP(54, 0);
-       case AFBLE:             return OP(51, 0);
-       case AFBGT:             return OP(55, 0);
-
-       case ATRAPB:            return OP(24, 0);
-       case AMB:               return OP(24, 0x200);
-       case AFETCH:            return OP(24, 0x400);
-       case AFETCHM:           return OP(24, 0x500);
-       case ARPCC:             return OP(24, 0x600);
-
-       case ACPYS:             return OP(23, 32);
-       case ACPYSN:            return OP(23, 33);
-       case ACPYSE:            return OP(23, 34);
-       case AADDS+AEND:        return OP(23, 37);      /* MF_FPCR */
-       case AADDT+AEND:        return OP(23, 36);      /* MT_FPCR */
-       case ACVTLQ:            return OP(23, 16);
-       case ACVTQL:            return OP(23, 48);      /* XXX trap mode */
-       case AFCMOVEQ:          return OP(23, 42);
-       case AFCMOVNE:          return OP(23, 43);
-       case AFCMOVLT:          return OP(23, 44);
-       case AFCMOVGE:          return OP(23, 45);
-       case AFCMOVLE:          return OP(23, 46);
-       case AFCMOVGT:          return OP(23, 47);
-
-       case AADDS:             return FP(0);
-       case AADDT:             return FP(32);
-       case ACMPTEQ:           return FP3(37);
-       case ACMPTGT:           return FP3(38);
-       case ACMPTGE:           return FP3(39);
-       case ACMPTUN:           return FP3(36);
-
-       case ACVTQS:            return FP2(60);
-       case ACVTQT:            return FP2(62);
-       case ACVTTS:            return FP2(44);
-       case ACVTTQ:            return FP2(47);
-
-       case ADIVS:             return FP(3);
-       case ADIVT:             return FP(35);
-       case AMULS:             return FP(2);
-       case AMULT:             return FP(34);
-       case ASUBS:             return FP(1);
-       case ASUBT:             return FP(33);
-
-       case ACALL_PAL:         return 0;
-       case AREI:              return OP(30, 0x400);   /* HW_REI */
+       Ieee *p;
+       int n;
 
-       case AADDQ+AEND:        return OP(25,0);        /* HW_MFPR */
-       case ASUBQ+AEND:        return OP(29,0);        /* HW_MTPR */
+       for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){
+               p = &chipfloats[n];
+               if(p->l == e->l && p->h == e->h && 0)
+                       return n;               /* TO DO: return imm8 encoding */
        }
-       diag("bad op %A(%d)", a, a);
-       return 0;
+       return -1;
 }
-