Annotation of lucent/sys/src/libgnot/bbv.h, revision 1.1.1.1

1.1       root        1: typedef        long    Type;
                      2: 
                      3: /*
                      4:  * See the comments at the beginning of gbitblt.c
                      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 RF to hold ~0 always, RX as a scratch register,
                     10:  *   and AT to hold the address of the table given in Inittab.
                     11:  */
                     12: #define As     5
                     13: #define Ad     6
                     14: #define        Rs      7
                     15: #define        Rd      8
                     16: #define Rt     9
                     17: #define Ru     10
                     18: #define Ri     11
                     19: #define Ro     12
                     20: #define RF     1       /* ~0 */
                     21: #define RX     2       /* scratch */
                     22: #define AT     3       /* conversion table */
                     23: 
                     24: /*
                     25:  * Macros for assembling MIPS instructions
                     26:  */
                     27: 
                     28: /* generate `a', `size' bits wide, into bit position `shift' */
                     29: /* the SMM version is used when there might be extra bits in `a' */
                     30: #define        SM(a,size,shift)        ((a)<<(shift))
                     31: #define        SMM(a,size,shift)       (((a)&(1<<(size))-1)<<(shift))
                     32: 
                     33: /* Make sure im fits in 16 bits and sh fits in 5 bits */
                     34: #define Iinst(op,rs,rt,im)     (SM(op,6,26)|SM(rs,5,21)|SM(rt,5,16)|(im))
                     35: #define Rinst(op,rs,rt,rd,sh,f)        (SM(op,6,26)|SM(rs,5,21)|SM(rt,5,16)|SM(rd,5,11)|SM(sh,5,6)|(f))
                     36: 
                     37: /*
                     38:  * Instructions
                     39:  */
                     40: 
                     41: #define SLL(rs,rd,sh)  Rinst(0,0,rs,rd,sh,0)
                     42: #define SRL(rs,rd,sh)  Rinst(0,0,rs,rd,sh,2)
                     43: #define ADDU(rs,rt,rd) Rinst(0,rs,rt,rd,0,041)
                     44: #define ADDIU(rs,rd,v) Iinst(011,rs,rd,v)
                     45: #define AND(rs,rt,rd)  Rinst(0,rs,rt,rd,0,044)
                     46: #define ANDI(rs,rd,v)  Iinst(014,rs,rd,v)
                     47: #define OR(rs,rt,rd)   Rinst(0,rs,rt,rd,0,045)
                     48: #define ORI(rs,rd,v)   Iinst(015,rs,rd,v)
                     49: #define XOR(rs,rt,rd)  Rinst(0,rs,rt,rd,0,046)
                     50: #define XORI(rs,rd,v)  Iinst(016,rs,rd,v)
                     51: #define NOR(rs,rt,rd)  Rinst(0,rs,rt,rd,0,047)
                     52: #define NOP            Rinst(0,0,0,0,0,047)
                     53: #define LUI(r,v)       Iinst(017,0,r,v)
                     54: #define LW(as,rd)      Iinst(043,as,rd,0)
                     55: #define LBU(as,rd)     Iinst(044,as,rd,0)
                     56: #define LHU(as,rd)     Iinst(045,as,rd,0)
                     57: #define SW(ad,rs)      Iinst(053,ad,rs,0)
                     58: #define BGTZ(r,d)      Iinst(007,r,0,d)
                     59: #define JR(r)          Rinst(0,r,0,0,0,010)
                     60: 
                     61: /*
                     62:  * Macros for assembling the operations of the abstract machine.
                     63:  * Each assumes that ulong *p points to the next location where
                     64:  * an instruction should be assembled.
                     65:  * These macros can use RX as a scratch register, but no others.
                     66:  * They can assume RF holds ~0.
                     67:  */
                     68: 
                     69: #define Ofield(c)      *p++ = XOR(Rs,Rd,Rs);                           \
                     70:                        if((c)&0xFFFF0000) {                            \
                     71:                                *p++ =  LUI(RX,((ulong)(c))>>16);       \
                     72:                                *p++ = ORI(RX,RX,(c)&0xFFFF);           \
                     73:                                *p++ = AND(RX,Rs,Rs);                   \
                     74:                        } else                                          \
                     75:                                *p++ = ANDI(Rs,Rs,(c));                 \
                     76:                        *p++ = XOR(Rs,Rd,Rs)
                     77: 
                     78: #define Olsha_RsRt     *p++ = SLL(Rt,Rs,sha)
                     79: #define Olshb_RsRt     *p++ = SLL(Rt,Rs,shb)
                     80: #define Olsh_RsRd(c)   *p++ = SLL(Rd,Rs,c)
                     81: #define Olsh_RtRt(c)   *p++ = SLL(Rt,Rt,c)
                     82: #define Olsha_RtRt     *p++ = SLL(Rt,Rt,sha)
                     83: #define Olsha_RtRu     *p++ = SLL(Ru,Rt,sha)
                     84: #define Olshb_RtRu     *p++ = SLL(Ru,Rt,shb)
                     85: #define Orsha_RsRt     *p++ = SRL(Rt,Rs,sha)
                     86: #define Orshb_RsRt     *p++ = SRL(Rt,Rs,shb)
                     87: #define Orsha_RtRu     *p++ = SRL(Ru,Rt,sha)
                     88: #define Orshb_RtRu     *p++ = SRL(Ru,Rt,shb)
                     89: #define Oorlsha_RsRt   *p++ = SLL(Rt,RX,sha); *p++ = OR(RX,Rs,Rs)
                     90: #define Oorlshb_RsRt   *p++ = SLL(Rt,RX,shb); *p++ = OR(RX,Rs,Rs)
                     91: #define Oorlsh_RsRd(c) *p++ = SLL(Rd,RX,c); *p++ = OR(RX,Rs,Rs)
                     92: #define Oorrsha_RsRt   *p++ = SRL(Rt,RX,sha); *p++ = OR(RX,Rs,Rs)
                     93: #define Oorrshb_RsRt   *p++ = SRL(Rt,RX,shb); *p++ = OR(RX,Rs,Rs)
                     94: #define Oorrsha_RtRu   *p++ = SRL(Ru,RX,sha); *p++ = OR(RX,Rt,Rt)
                     95: #define Oorrshb_RtRu   *p++ = SRL(Ru,RX,shb); *p++ = OR(RX,Rt,Rt)
                     96: #define Oor_RsRd       *p++ = OR(Rs,Rd,Rs)
                     97: 
                     98: /*
                     99:  * Try to use smaller instructions when the constant is small.
                    100:  * Note that MIPS sign extends immediate operands
                    101:  */
                    102: #define Add_As(c)      if((c)&0xFFFF8000) { \
                    103:                                if(!((c)&0xFFFF0000)) { \
                    104:                                        *p++ = ORI(0,RX,(c)&0xFFFF); \
                    105:                                        *p++ = ADDU(RX,As,As); \
                    106:                                } else { \
                    107:                                        *p++ = LUI(RX,((ulong)(c))>>16); \
                    108:                                        *p++ = ORI(RX,RX,(c)&0xFFFF); \
                    109:                                        *p++ = ADDU(RX,As,As); \
                    110:                                } \
                    111:                        } else \
                    112:                                *p++ = ADDIU(As,As,c)
                    113: 
                    114: #define Add_Ad(c)      if((c)&0xFFFF8000) { \
                    115:                                if(!((c)&0xFFFF0000)) { \
                    116:                                        *p++ = ORI(0,RX,(c)&0xFFFF); \
                    117:                                        *p++ = ADDU(RX,Ad,Ad); \
                    118:                                } else { \
                    119:                                        *p++ = LUI(RX,((ulong)(c))>>16); \
                    120:                                        *p++ = ORI(RX,RX,(c)&0xFFFF); \
                    121:                                        *p++ = ADDU(RX,Ad,Ad); \
                    122:                                } \
                    123:                        } else \
                    124:                                *p++ = ADDIU(Ad,Ad,c)
                    125: 
                    126: #define Initsd(s,d)    *p++ = LUI(As,((ulong)(s))>>16); \
                    127:                        *p++ = ORI(As,As,((ulong)(s))&0xFFFF); \
                    128:                        *p++ = LUI(Ad,((ulong)(d))>>16); \
                    129:                        *p++ = ORI(Ad,Ad,((ulong)(d))&0xFFFF)
                    130: 
                    131: #define Initsh(a,b)
                    132: 
                    133: /* Put all ones in RF */
                    134: #define Extrainit      *p++ = ADDIU(0,RF,0xFFFF)
                    135: 
                    136: /*
                    137:  * We put one less than the loop count into R[io], so that
                    138:  * the loop instructions can decrement after the test instead
                    139:  * of before
                    140:  */
                    141: #define Ilabel(c)      tmp = (c)-1; \
                    142:                        if(tmp&0xFFFF8000) { \
                    143:                                *p++ = LUI(Ri,((ulong)tmp)>>16); \
                    144:                                *p++ = ORI(Ri,Ri,tmp&0xFFFF); \
                    145:                        } else \
                    146:                                *p++ = ADDIU(0,Ri,tmp)
                    147: 
                    148: #define Olabel(c)      tmp = (c)-1; \
                    149:                        if(tmp&0xFFFF8000) { \
                    150:                                *p++ = LUI(Ro,((ulong)tmp)>>16); \
                    151:                                *p++ = ORI(Ro,Ro,tmp&0xFFFF); \
                    152:                        } else \
                    153:                                *p++ = ADDIU(0,Ro,tmp)
                    154: 
                    155: /*
                    156:  * The decrement is done after the test instead of before
                    157:  * so that the required delay slot can be filled with
                    158:  * the decrement (counts were adjusted by [IO]label)
                    159:  */
                    160: #define Iloop(lp)      *p = BGTZ(Ri,(lp-(p+1))&0xFFFF); p++; \
                    161:                        *p++ = ADDIU(Ri,Ri,0xFFFF)
                    162: 
                    163: #define Oloop(lp)      *p = BGTZ(Ro,(lp-(p+1))&0xFFFF); p++; \
                    164:                        *p++ = ADDIU(Ro,Ro,0xFFFF)
                    165: 
                    166: #define Orts           *p++ = JR(31); *p++ = NOP
                    167: 
                    168: /*
                    169:  * Load and Fetch macros: arg should be 1 if following instr might use loaded value
                    170:  * In the predecrement versions, it's as easy to do the decrment afterwards in
                    171:  * the delay slot
                    172:  */
                    173: 
                    174: #define Load_Rs_P      *p++ = LW(As,Rs); *p++ = ADDIU(As,As,4)
                    175: #define Load_Rt_P      *p++ = LW(As,Rt); *p++ = ADDIU(As,As,4)
                    176: #define Loadzx_Rt_P    *p++ = LW(As,Rt); *p++ = ADDIU(As,As,4)
                    177: #define Loador_Rt_P    *p++ = LW(As,Rt); *p++ = ADDIU(As,As,4)
                    178: #define Load_Ru_P      *p++ = LW(As,Ru); *p++ = ADDIU(As,As,4)
                    179: #define Load_Rd_D(f)   *p++ = ADDIU(As,As,-4&0xFFFF); *p++ = LW(As,Rd); \
                    180:                        if(f) *p++ = NOP
                    181: #define Load_Rs_D(f)   *p++ = ADDIU(As,As,-4&0xFFFF); *p++ = LW(As,Rs); \
                    182:                        if(f) *p++ = NOP
                    183: #define Load_Rt_D(f)   *p++ = ADDIU(As,As,-4&0xFFFF); *p++ = LW(As,Rt); \
                    184:                        if(f) *p++ = NOP
                    185: #define Loadzx_Rt_D(f) *p++ = ADDIU(As,As,-4&0xFFFF); *p++ = LW(As,Rt); \
                    186:                        if(f) *p++ = NOP
                    187: #define Load_Rd(f)     *p++ = LW(As,Rd); if(f) *p++ = NOP
                    188: #define Load_Rs(f)     *p++ = LW(As,Rs); if(f) *p++ = NOP
                    189: #define Load_Rt(f)     *p++ = LW(As,Rt); if(f) *p++ = NOP
                    190: #define Loadzx_Rt(f)   *p++ = LW(As,Rt); if(f) *p++ = NOP
                    191: #define Fetch_Rd_P(f)  *p++ = LW(Ad,Rd); *p++ = ADDIU(Ad,Ad,4)
                    192: #define Fetch_Rd_D(f)  *p++ = ADDIU(Ad,Ad,-4&0xFFFF); *p++ = LW(Ad,Rd); \
                    193:                        if(f) *p++ = NOP
                    194: #define Fetch_Rd(f)    *p++ = LW(Ad,Rd); if(f) *p++ = NOP
                    195: #define Store_Rs_P     *p++ = SW(Ad,Rs); *p++ = ADDIU(Ad,Ad,4)
                    196: #define Store_Rs_D     *p++ = ADDIU(Ad,Ad,-4&0xFFFF); *p++ = SW(Ad,Rs)
                    197: #define Store_Rs       *p++ = SW(Ad,Rs)
                    198: #define Nop            *p++ = NOP
                    199: 
                    200: #define Inittab(t,s)   *p++ = LUI(AT,((ulong)(t))>>16); \
                    201:                        *p++ = ORI(AT,AT,((ulong)(t))&0xFFFF)
                    202: 
                    203: /* emit code to look up n bits at offset o; table entries are 1<<l bytes long */
                    204: #define Table_RdRt(o,n,l)                      \
                    205:        tmp = 32-((o)+(n))-(l);                 \
                    206:        if(tmp > 0)                             \
                    207:                *p++ = SRL(Rt,Rd,tmp);          \
                    208:        else if((l) > 0)                        \
                    209:                *p++ = SLL(Rt,Rd,l);            \
                    210:        else                                    \
                    211:                *p++ = ADDU(Rt,0,Rd);           \
                    212:        *p++ = ANDI(Rd,Rd,((1<<(n))-1)<<(l));   \
                    213:        *p++ = ADDU(Rd,AT,Rd);                  \
                    214:        if(osiz==1) *p++ = LBU(Rd,Rd);          \
                    215:        else if(osiz==2) *p++ = LHU(Rd,Rd);     \
                    216:        else *p++ = LW(Rd,Rd);                  \
                    217:        *p++ = NOP
                    218: 
                    219: #define Table_RsRt(o,n,l)                      \
                    220:        tmp = 32-((o)+(n))-(l);                 \
                    221:        if(tmp > 0)                             \
                    222:                *p++ = SRL(Rt,Rs,tmp);          \
                    223:        else if((l) > 0)                        \
                    224:                *p++ = SLL(Rt,Rs,l);            \
                    225:        else                                    \
                    226:                *p++ = ADDU(Rt,0,Rs);           \
                    227:        *p++ = ANDI(Rd,Rs,((1<<(n))-1)<<(l));   \
                    228:        *p++ = ADDU(Rs,AT,Rs);                  \
                    229:        if(osiz==1) *p++ = LBU(Rs,Rs);          \
                    230:        else if(osiz==2) *p++ = LHU(Rs,Rs);     \
                    231:        else *p++ = LW(Rs,Rs);                  \
                    232:        *p++ = NOP
                    233: 
                    234: /* emit code to assemble low n bits of Rd into offset o in Rs */
                    235: #define Assemble(o,n)                          \
                    236:        if((o) == 0) {                          \
                    237:                Olsh_RsRd(32-(n));              \
                    238:        } else if((o) == 32-(n)) {              \
                    239:                *p++ = OR(Rs,Rd,Rs);            \
                    240:        } else {                                \
                    241:                Oorlsh_RsRd(32-((o)+(n)));      \
                    242:        }
                    243: 
                    244: /* emit code to assemble low n bits of Rd into offset o in Rs.
                    245:    this works by shifting Rd as we go, it only works if
                    246:    the whole word will eventually be filled */
                    247: #define Assemblex(o,n)                         \
                    248:        if((o) == 0) {                          \
                    249:                *p++ = ADDU(Rd,0,Rs);           \
                    250:        } else {                                \
                    251:                *p++ = SLL(Rs,Rs,n);            \
                    252:                *p++ = OR(Rd,Rs,Rs);            \
                    253:        }
                    254: 
                    255: #define Emitop                 \
                    256:        p[0] = fi[0];           \
                    257:        p[1] = fi[1];           \
                    258:        p = (Type*)(((char *)p)+fin)
                    259: 
                    260: typedef struct Fstr
                    261: {
                    262:        char    fetchs;
                    263:        char    fetchd;
                    264:        short   n;
                    265:        Type    instr[2];
                    266: } Fstr;
                    267: 
                    268: Fstr   fstr[16] =
                    269: {
                    270: [0]    0,0,4,          /* Zero */
                    271:        { LUI(Rs,0), 0 },
                    272: 
                    273: [1]    1,1,4,          /* DnorS */
                    274:        { NOR(Rs,Rd,Rs), 0 },
                    275: 
                    276: [2]    1,1,8,          /* DandnotS */
                    277:        { XOR(Rs,RF,Rs), AND(Rs,Rd,Rs) },
                    278: 
                    279: [3]    1,0,4,          /* notS */
                    280:        { XOR(Rs,RF,Rs), 0 },
                    281: 
                    282: [4]    1,1,8,          /* notDandS */
                    283:        { XOR(Rs,RF,Rs), NOR(Rd,Rs,Rs) },
                    284: 
                    285: [5]    0,1,4,          /* notD */
                    286:        { XOR(Rd,RF,Rs), 0 },
                    287: 
                    288: [6]    1,1,4,          /* DxorS */
                    289:        { XOR(Rd,Rs,Rs), 0 },
                    290: 
                    291: [7]    1,1,8,          /* DnandS */
                    292:        { AND(Rd,Rs,Rs), XOR(Rs,RF,Rs) },
                    293: 
                    294: [8]    1,1,4,          /* DandS */
                    295:        { AND(Rd,Rs,Rs), 0 },
                    296: 
                    297: [9]    1,1,8,          /* DxnorS */
                    298:        { XOR(Rd,Rs,Rs), XOR(Rs,RF,Rs) },
                    299: 
                    300: [10]   0,1,4,          /* D */
                    301:        { ADDU(Rd,0,Rs), 0 },
                    302: 
                    303: [11]   1,1,8,          /* DornotS */
                    304:        { XOR(Rs,RF,Rs), OR(Rs,Rd,Rs) },
                    305: 
                    306: [12]   1,0,0,          /* S */
                    307:        {0, 0},
                    308: 
                    309: [13]   1,1,8,          /* notDorS */
                    310:        { XOR(Rd,RF,RX), OR(Rs,RX,Rs) },
                    311: 
                    312: [14]   1,1,4,          /* DorS */
                    313:        { OR(Rs,Rd,Rs), 0 },
                    314: 
                    315: [15]   0,0,4,          /* F */
                    316:        { OR(RF,0,Rs), 0 },
                    317: };
                    318: 
                    319: #include "tabs.h"
                    320: static uchar *tabs[4][4] =
                    321: {
                    322:        {            0, (uchar*)tab01, (uchar*)tab02, (uchar*)tab03},
                    323:        {(uchar*)tab10,             0, (uchar*)tab12, (uchar*)tab13},
                    324:        {(uchar*)tab20, (uchar*)tab21,             0, (uchar*)tab23},
                    325:        {(uchar*)tab30, (uchar*)tab31, (uchar*)tab32,             0},
                    326: };
                    327: 
                    328: static uchar tabosiz[4][4] = /* size in bytes of entries */
                    329: {
                    330:        { 0, 2, 4, 4},
                    331:        { 1, 0, 2, 4},
                    332:        { 1, 1, 0, 2},
                    333:        { 1, 1, 1, 0},
                    334: };
                    335: 
                    336: enum {
                    337:        Progmax = 900,          /* max number of Type units in a bitblt prog */
                    338:        Progmaxnoconv = 64,     /* max number of Type units when no conversion */
                    339: };
                    340: 
                    341: void
                    342: prprog(void)
                    343: {
                    344:        abort();        /* use db */
                    345: }

unix.superglobalmegacorp.com

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