Annotation of lucent/sys/src/libgnot/bb2.h, revision 1.1

1.1     ! root        1: typedef        ushort  Type;
        !             2: 
        !             3: /*
        !             4:  * See the comments at the beginning of bb.c and bbc.h
        !             5:  * for an outline of how this bitblt works
        !             6:  
        !             7:  * Registers
        !             8:  *   in addition to the registers of the abstract machine,
        !             9:  *   we use RY as a scratch register, and AT to hold the
        !            10:  *   address of the table given in Inittab.
        !            11:  */
        !            12: /* A registers */
        !            13: #define As     0
        !            14: #define Ad     1
        !            15: #define AT     2       /* conversion table */
        !            16: #define Ao     3       /* Ro in abstract machine */
        !            17: #define Au     4       /* Ru in abstract machine */
        !            18: /* D registers */
        !            19: #define        Rs      0
        !            20: #define        Rd      1
        !            21: #define Rt     2
        !            22: #define Ri     3
        !            23: #define Ra     4       /* shift a */
        !            24: #define Rb     5       /* shift b */
        !            25: #define RX     6       /* scratch */
        !            26: #define RY     7       /* scratch */
        !            27: 
        !            28: /*
        !            29:  * Addressing modes
        !            30:  */
        !            31: /* use Rx by itself to get Dn mode */
        !            32: #define AR(n)          ((1<<3)|n)      /* An */
        !            33: #define AI(n)          ((2<<3)|n)      /* (An) */
        !            34: #define AIPOST(n)      ((3<<3)|n)      /* (An)+ */
        !            35: #define AIPRE(n)       ((4<<3)|n)      /* -(An) */
        !            36: #define AID(n)         ((5<<3)|n)      /* d16(An) */
        !            37: #define AIX(n)         ((6<<3)|n)      /* (An+Xm) with following word */
        !            38: #define AIXEXT(m)      ((m<<12)|(1<<11))               /* scale factor 1 */
        !            39: #define AIX2EXT(m)     ((m<<12)|(1<<11)|(1<<9))        /* scale factor 2 */
        !            40: #define AIX4EXT(m)     ((m<<12)|(1<<11)|(2<<9))        /* scale factor 4 */
        !            41: #define IMML           ((7<<3)|4)      /* immediate long (following) */
        !            42: #define ABSW           ((7<<3)|0)      /* absolute short address */
        !            43: 
        !            44: /* generate `a', `size' bits wide, into bit position `shift' */
        !            45: /* the SMM version is used when there might be extra bits in `a' */
        !            46: #define        SM(a,size,shift)        ((a)<<(shift))
        !            47: #define        SMM(a,size,shift)       (((a)&(1<<(size))-1)<<(shift))
        !            48: /*
        !            49:  * Instructions
        !            50:  *   They operate on long words, unless suffixed by 'w' or 'b'
        !            51:  *   The 'I' instructions must be followed by immediate data (bigendian)
        !            52:  */
        !            53: 
        !            54: #define MOVE(dmode,smode) (SM(2,4,12)|SMM(dmode,3,9)|SMM((dmode>>3),3,6)|SM(smode,6,0))
        !            55: #define MOVEw(dmode,smode) (SM(3,4,12)|SMM(dmode,3,9)|SMM((dmode>>3),3,6)|SM(smode,6,0))
        !            56: #define MOVEb(dmode,smode) (SM(1,4,12)|SMM(dmode,3,9)|SMM((dmode>>3),3,6)|SM(smode,6,0))
        !            57: #define MOVEQ(dreg,v)  (SM(0x7,4,12)|SM(dreg,3,9)|SM(v,8,0))
        !            58:        /* MOVEQ sign-extends the 8-bit value; make sure it is masked to 8 bits */
        !            59: 
        !            60: #define AND(dreg,smode)        (SM(0xC,4,12)|SM(dreg,3,9)|SM(2,3,6)|SM(smode,6,0))
        !            61: #define ANDI(dmode)    (SM(0x02,8,8)|SM(2,2,6)|SM(dmode,6,0))
        !            62: #define ANDIw(dmode)   (SM(0x02,8,8)|SM(1,2,6)|SM(dmode,6,0))
        !            63: 
        !            64: /* the 68020 gnot.h defines an OR */
        !            65: #undef OR
        !            66: #define OR(dreg,smode) (SM(0x8,4,12)|SM(dreg,3,9)|SM(2,3,6)|SM(smode,6,0))
        !            67: #define XOR(dmode,sreg)        (SM(0xB,4,12)|SM(sreg,3,9)|SM(6,3,6)|SM(dmode,6,0))
        !            68: #define NOT(dmode)     (SM(0x46,8,8)|SM(2,2,6)|SM(dmode,6,0))
        !            69: #define CLR(dmode)     (SM(0x42,8,8)|SM(2,2,6)|SM(dmode,6,0))
        !            70: 
        !            71: /* LS[LR] can shift 1-8 (n==8 gets smashed to 0, which is the right encoding) */
        !            72: /* else have to put shift amount in reg and use LS[LR]R */
        !            73: #define LSL(dreg,n)    (SM(0xE,4,12)|SMM(n,3,9)|SM(1,1,8)|SM(0x11,5,3)|SM(dreg,3,0))
        !            74: #define LSLR(dreg,rn)  (SM(0xE,4,12)|SM(rn,3,9)|SM(1,1,8)|SM(0x15,5,3)|SM(dreg,3,0))
        !            75: 
        !            76: #define LSR(dreg,n)    (SM(0xE,4,12)|SMM(n,3,9)|SM(0,1,8)|SM(0x11,5,3)|SM(dreg,3,0))
        !            77: #define LSRR(dreg,rn)  (SM(0xE,4,12)|SM(rn,3,9)|SM(0,1,8)|SM(0x15,5,3)|SM(dreg,3,0))
        !            78: 
        !            79: #define ADDA(dareg,smode) (SM(0xD,4,12)|SM(dareg,3,9)|SM(7,3,6)|SM(smode,6,0))
        !            80: #define ADDQ(dmode,v)  (SM(0x5,4,12)|SMM(v,3,9)|SM(0,1,8)|SM(2,2,6)|SM(dmode,6,0))
        !            81: #define SUBQ(dmode,v)  (SM(0x5,4,12)|SMM(v,3,9)|SM(1,1,8)|SM(2,2,6)|SM(dmode,6,0))
        !            82: #define LEA(dareg,smode) (SM(0x4,4,12)|SM(dareg,3,9)|SM(7,3,6)|SM(smode,6,0))
        !            83: 
        !            84: /* BFEXTU and BFINS each must be followed by BFIELD */
        !            85: #define BFEXTU(smode)  (SM(0xE9,8,8)|SM(3,2,6)|SM(smode,6,0))
        !            86: #define BFINS(dmode)   (SM(0xEF,8,8)|SM(3,2,6)|SM(dmode,6,0))
        !            87: 
        !            88: /* low part of r is dst for BFEXTU, src for BFINS */
        !            89: /* offset is from high order bit; w==0 means width of 32 */
        !            90: #define BFIELD(r,o,w)  (SM(r,3,12)|SM(o,5,6)|SMM(w,5,0))
        !            91: 
        !            92: #define DBF(countreg)  (SM(0x5,4,12)|SM(0x39,6,3)|SM(countreg,3,0))
        !            93: 
        !            94: #define BCC(cond,d8)   (SM(0x6,4,12)|SM(cond,4,8)|SMM(d8,8,0))
        !            95: 
        !            96: #define RTS            0x4E75
        !            97: 
        !            98: /*
        !            99:  * Macros for assembling the operations of the abstract machine.
        !           100:  * Each assumes that ushort *p points to the next location where
        !           101:  * an instruction should be assembled.
        !           102:  * These macros can use RY as a scratch register, but no others.
        !           103:  */
        !           104: 
        !           105: #define Two(h,l)       *(long *)p = (long)(((h)<<16)|(l)); p += 2
        !           106: #define Lsh(r,n)       if(n != 0) { \
        !           107:                                if(n <= 8) \
        !           108:                                        *p++ = LSL(r,n); \
        !           109:                                else { \
        !           110:                                        *p++ = MOVEQ(RX,n); *p++ = LSLR(r,RX); \
        !           111:                                } \
        !           112:                        }
        !           113: #define Rsh(r,n)       if(n != 0) { \
        !           114:                                if(n <= 8) \
        !           115:                                        *p++ = LSR(r,n); \
        !           116:                                else { \
        !           117:                                        *p++ = MOVEQ(RX,n); *p++ = LSRR(r,RX); \
        !           118:                                } \
        !           119:                        }
        !           120: #define Lsha(r)                *p++ = LSLR(r,Ra)
        !           121: #define Lshb(r)                *p++ = LSLR(r,Rb)
        !           122: #define Rsha(r)                *p++ = LSRR(r,Ra)
        !           123: #define Rshb(r)                *p++ = LSRR(r,Rb)
        !           124: #define Andcon(r,c)    *p++ = ANDI(r); *(long *)p = (long)(c); p += 2
        !           125: #define Movecon(r,c)   *p++ = MOVE(r,IMML); *(long *)p = (long)(c); p += 2
        !           126: #define Moveacon(dareg,c) *p++ = MOVE(AR(dareg),IMML);  *(long *)p = (long)(c); p += 2
        !           127: /* Addacon assumes value added will fit in a short */
        !           128: #define Addacon(dareg,c) *p++ = LEA(dareg,AID(dareg)); *p++ = c
        !           129: /* Bcc assumes distance to branch is less than short offset */
        !           130: #define Bcc(cond,lp)   *p++ = BCC(cond,0); *p++ = ((char*)(lp))-(((char*)p))
        !           131: #define Ofield(c)      *p++ = XOR(Rs,Rd); Andcon(Rs,c); *p++ = XOR(Rs,Rd)
        !           132: #define Olsha_RsRt     *p++ = MOVE(Rs,Rt); Lsha(Rs)
        !           133: #define Olshb_RsRt     *p++ = MOVE(Rs,Rt); Lshb(Rs)
        !           134: #define Olsh_RsRd(c)   *p++ = MOVE(Rs,Rd); Lsh(Rs,c)
        !           135: #define Olsh_RtRt(c)   Lsh(Rt,c)
        !           136: #define Olsha_RtRt     Lsha(Rt)
        !           137: #define Olsha_RtRu     Two(MOVE(Rt,AR(Au)),LSLR(Rt,Ra))
        !           138: #define Olshb_RtRu     Two(MOVE(Rt,AR(Au)),LSLR(Rt,Rb))
        !           139: #define Orsha_RsRt     Two(MOVE(Rs,Rt),LSRR(Rs,Ra))
        !           140: #define Orshb_RsRt     Two(MOVE(Rs,Rt),LSRR(Rs,Rb))
        !           141: #define Orsha_RtRu     Two(MOVE(Rt,AR(Au)),LSRR(Rt,Ra))
        !           142: #define Orshb_RtRu     Two(MOVE(Rt,AR(Au)),LSRR(Rt,Rb))
        !           143: #define Oorlsha_RsRt   Two(MOVE(RY,Rt),LSLR(RY,Ra)); *p++ = OR(Rs,RY)
        !           144: #define Oorlshb_RsRt   Two(MOVE(RY,Rt),LSLR(RY,Rb)); *p++ = OR(Rs,RY)
        !           145: #define Oorlsh_RsRd(c) *p++ = MOVE(RY,Rd); Lsh(RY,c); *p++ = OR(Rs,RY)
        !           146: #define Oorrsha_RsRt   Two(MOVE(RY,Rt),LSRR(RY,Ra)); *p++ = OR(Rs,RY)
        !           147: #define Oorrshb_RsRt   Two(MOVE(RY,Rt),LSRR(RY,Rb)); *p++ = OR(Rs,RY)
        !           148: #define Oorrsha_RtRu   Two(MOVE(RY,AR(Au)),LSRR(RY,Ra)); *p++ = OR(Rt,RY)
        !           149: #define Oorrshb_RtRu   Two(MOVE(RY,AR(Au)),LSRR(RY,Rb)); *p++ = OR(Rt,RY)
        !           150: #define Oor_RsRd       *p++ = OR(Rs,Rd)
        !           151: #define Add_As(c)      Addacon(As,c)
        !           152: #define Add_Ad(c)      Addacon(Ad,c)
        !           153: #define Initsd(s,d)    *p++ = MOVE(AR(As),IMML); *(long *)p = (long) (s); p += 2; \
        !           154:                        *p++ = MOVE(AR(Ad),IMML); *(long *)p = (long) (d); p += 2
        !           155: #define Initsh(a,b)    *p++ = MOVEQ(Ra,a); *p++ = MOVEQ(Rb,b)
        !           156: 
        !           157: /*
        !           158:  * use DBF instruction. assume counts < 16k
        !           159:  */
        !           160: #define Ilabel(c)      tmp = (c)-1; Movecon(Ri,tmp)
        !           161: #define Olabel(c)      Moveacon(Ao,(c))
        !           162: #define Iloop(lp)      *p++ = DBF(Ri); *p++ = ((char*)(lp))-((char*)p)
        !           163: #define Oloop(lp)      *p++ = SUBQ(AR(Ao),1); *p++ = MOVE(Rs,AR(Ao)); \
        !           164:                        Bcc(0x6,lp) /* Bne */
        !           165: 
        !           166: #define Orts           *p++ = RTS
        !           167: #define Nop            /* nothing */
        !           168: 
        !           169: /*
        !           170:  * Load and Fetch macros: arg is ignored for this architecture
        !           171:  */
        !           172: 
        !           173: #define Load_Rs_P      *p++ = MOVE(Rs,AIPOST(As))
        !           174: #define Load_Rt_P      *p++ = MOVE(Rt,AIPOST(As))
        !           175: #define Loadzx_Rt_P    *p++ = MOVE(Rt,AIPOST(As))
        !           176: #define Loador_Rt_P    *p++ = MOVE(Rt,AIPOST(As))
        !           177: #define Load_Ru_P      *p++ = MOVE(AR(Au),AIPOST(As))
        !           178: #define Load_Rd_D(f)   *p++ = MOVE(Rd,AIPRE(As))
        !           179: #define Load_Rs_D(f)   *p++ = MOVE(Rs,AIPRE(As))
        !           180: #define Load_Rt_D(f)   *p++ = MOVE(Rt,AIPRE(As))
        !           181: #define Loadzx_Rt_D(f) *p++ = MOVE(Rt,AIPRE(As))
        !           182: #define Load_Rd(f)     *p++ = MOVE(Rd,AI(As))
        !           183: #define Load_Rs(f)     *p++ = MOVE(Rs,AI(As))
        !           184: #define Load_Rt(f)     *p++ = MOVE(Rt,AI(As))
        !           185: #define Loadzx_Rt(f)   *p++ = MOVE(Rt,AI(As))
        !           186: #define Fetch_Rd_P(f)  *p++ = MOVE(Rd,AIPOST(Ad))
        !           187: #define Fetch_Rd_D(f)  *p++ = MOVE(Rd,AIPRE(Ad))
        !           188: #define Fetch_Rd(f)    *p++ = MOVE(Rd,AI(Ad))
        !           189: #define Store_Rs_P     *p++ = MOVE(AIPOST(Ad),Rs)
        !           190: #define Store_Rs_D     *p++ = MOVE(AIPRE(Ad),Rs)
        !           191: #define Store_Rs       *p++ = MOVE(AI(Ad),Rs)
        !           192: 
        !           193: #define HAVEBF
        !           194: #define Bfextu_RdAd(o,w) *p++ = BFEXTU(AI(Ad)); *p++ = BFIELD(Rd,o,w)
        !           195: #define Bfextu_RsAs(o,w) *p++ = BFEXTU(AI(As)); *p++ = BFIELD(Rs,o,w)
        !           196: #define Bfins_AdRs(o,w)  *p++ = BFINS(AI(Ad)); *p++ = BFIELD(Rs,o,w)
        !           197: 
        !           198: #define Inittab(t,s)   *p++ = MOVE(AR(AT),IMML); *(long *)p = (long) t; p += 2
        !           199: 
        !           200: /* look up n bits at offset o in Rt; move table entry (1<<l bytes long) to Rd */
        !           201: #define Table_RdRt(o,n,l) Two(BFEXTU(Rt),BFIELD(Rd,o,n)); \
        !           202:                        if(osiz==1) { \
        !           203:                                Two(MOVEb(Rd,AIX(AT)),AIXEXT(Rd)); \
        !           204:                        } else if(osiz==2) { \
        !           205:                                Two(MOVEw(Rd,AIX(AT)),AIX2EXT(Rd)); \
        !           206:                        } else { \
        !           207:                                Two(MOVE(Rd,AIX(AT)),AIX4EXT(Rd)); \
        !           208:                        }
        !           209: 
        !           210: #define Table_RsRt(o,n,l) Two(BFEXTU(Rt),BFIELD(Rs,o,n)); \
        !           211:                        if(osiz==1) { \
        !           212:                                Two(MOVEb(Rs,AIX(AT)),AIXEXT(Rs)); \
        !           213:                        } else if(osiz==2) { \
        !           214:                                Two(MOVEw(Rs,AIX(AT)),AIX2EXT(Rs)); \
        !           215:                        } else { \
        !           216:                                Two(MOVE(Rs,AIX(AT)),AIX4EXT(Rs)); \
        !           217:                        }
        !           218: 
        !           219: /* emit code to assemble low n bits of Rd into offset o in Rs */
        !           220: #define Assemble(o,n)                          \
        !           221:        if((o) == 0) {                          \
        !           222:                Olsh_RsRd(32-(n));              \
        !           223:        } else if((o) == 32-(n)) {              \
        !           224:                *p++ = OR(Rs,Rd);               \
        !           225:        } else {                                \
        !           226:                Oorlsh_RsRd(32-((o)+(n)));      \
        !           227:        }
        !           228: /* emit code to assemble low n bits of Rd into offset o in Rs.
        !           229:    this works by shifting Rd as we go, it only works if
        !           230:    the whole word will eventually be filled */
        !           231: #define Assemblex(o,n)                         \
        !           232:        if((o) == 0) {                          \
        !           233:                *p++ = MOVE(Rs,Rd);             \
        !           234:        } else {                                \
        !           235:                Lsh(Rs,n);                      \
        !           236:                *p++ = OR(Rs,Rd);               \
        !           237:        }
        !           238: 
        !           239: #define Extrainit
        !           240: 
        !           241: extern void    flushvirtpage(void *);
        !           242: extern void    bbdflush(void *, int);
        !           243: 
        !           244: #define Execandfree(memstart,onstack)                                  \
        !           245:                        if(onstack) {                                   \
        !           246:                                flushvirtpage(memstart);                \
        !           247:                                (*(void (*)(void))memstart)();          \
        !           248:                        } else {                                        \
        !           249:                                tmp = (p-memstart) * sizeof(Type);      \
        !           250:                                bbdflush(memstart, tmp);                \
        !           251:                                (*(void (*)(void))memstart)();          \
        !           252:                                bbfree(memstart, tmp);                  \
        !           253:                        }
        !           254: 
        !           255: /* emit code seq at fi (at most 3 shorts) */
        !           256: #define Emitop                                 \
        !           257:        *(long *)p = *(long *)fi;               \
        !           258:        p[2] = fi[2];                           \
        !           259:        p = (Type*)(((char *)p)+fin)
        !           260: 
        !           261: typedef struct Fstr
        !           262: {
        !           263:        short   fetchs;
        !           264:        short   fetchd;
        !           265:        int     n;
        !           266:        Type    instr[4];
        !           267: } Fstr;
        !           268: 
        !           269: Fstr   fstr[16] =
        !           270: {
        !           271: [0]    0,0,2,          /* Zero */
        !           272:        { CLR(Rs), 0, 0, 0 },
        !           273: 
        !           274: [1]    1,1,4,          /* DnorS */
        !           275:        { OR(Rs,Rd), NOT(Rs), 0, 0},
        !           276: 
        !           277: [2]    1,1,4,          /* DandnotS */
        !           278:        { NOT(Rs), AND(Rs,Rd), 0, 0},
        !           279: 
        !           280: [3]    1,0,2,          /* notS */
        !           281:        { NOT(Rs), 0, 0, 0},
        !           282: 
        !           283: [4]    1,1,6,          /* notDandS */
        !           284:        { NOT(Rs), OR(Rs,Rd), NOT(Rs), 0},
        !           285: 
        !           286: [5]    0,1,4,          /* notD */
        !           287:        { MOVE(Rs,Rd), NOT(Rs), 0, 0},
        !           288: 
        !           289: [6]    1,1,2,          /* DxorS */
        !           290:        { XOR(Rs,Rd), 0, 0, 0},
        !           291: 
        !           292: [7]    1,1,4,          /* DnandS */
        !           293:        { AND(Rs,Rd), NOT(Rs), 0, 0},
        !           294: 
        !           295: [8]    1,1,2,          /* DandS */
        !           296:        { AND(Rs,Rd), 0, 0, 0},
        !           297: 
        !           298: [9]    1,1,4,          /* DxnorS */
        !           299:        { XOR(Rs,Rd), NOT(Rs), 0, 0},
        !           300: 
        !           301: [10]   0,1,2,          /* D */
        !           302:        { MOVE(Rs,Rd), 0, 0, 0},
        !           303: 
        !           304: [11]   1,1,4,          /* DornotS */
        !           305:        { NOT(Rs), OR(Rs,Rd), 0, 0},
        !           306: 
        !           307: [12]   1,0,0,          /* S */
        !           308:        { 0, 0, 0, 0},
        !           309: 
        !           310: [13]   1,1,6,          /* notDorS */
        !           311:        { NOT(Rs), AND(Rs,Rd), NOT(Rs), 0},
        !           312: 
        !           313: [14]   1,1,2,          /* DorS */
        !           314:        { OR(Rs,Rd), 0, 0, 0},
        !           315: 
        !           316: [15]   0,0,4,          /* F */
        !           317:        { CLR(Rs), NOT(Rs), 0, 0},
        !           318: };
        !           319: 
        !           320: #include "tabs.h"
        !           321: static uchar *tabs[4][4] =
        !           322: {
        !           323:        {            0, (uchar*)tab01, (uchar*)tab02, (uchar*)tab03},
        !           324:        {(uchar*)tab10,             0, (uchar*)tab12, (uchar*)tab13},
        !           325:        {(uchar*)tab20, (uchar*)tab21,             0, (uchar*)tab23},
        !           326:        {(uchar*)tab30, (uchar*)tab31, (uchar*)tab32,             0},
        !           327: };
        !           328: 
        !           329: static uchar tabosiz[4][4] = /* size in bytes of entries */
        !           330: {
        !           331:        { 0, 2, 4, 4},
        !           332:        { 1, 0, 2, 4},
        !           333:        { 1, 1, 0, 2},
        !           334:        { 1, 1, 1, 0},
        !           335: };
        !           336: 
        !           337: enum {
        !           338:        Progmax = 1600,         /* max number of Type units in a bitblt prog */
        !           339:                                /* should be bigger if want 0->5 conversion */
        !           340:        Progmaxnoconv = 80,     /* max number of Type units when no conversion */
        !           341: };
        !           342: 
        !           343: #ifdef TEST
        !           344: 
        !           345: void
        !           346: prprog(void)
        !           347: {
        !           348:        abort();        /* use db */
        !           349: }
        !           350: 
        !           351: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.