Annotation of lucent/sys/src/libgnot/bb2.h, revision 1.1.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.