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

1.1       root        1: typedef        long    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 RF to hold ~0 always, RX as a scratch register,
                     10:  *   Rc as a scratch register for forming constants, and
                     11:  *   AT to hold the address of the table given in Inittab.
                     12:  */
                     13: #define        R0      0
                     14: #define As     19
                     15: #define Ad     20
                     16: #define        Rs      21
                     17: #define        Rd      22
                     18: #define Rt     23
                     19: #define Ru     24
                     20: #define Ri     25
                     21: #define Ro     26
                     22: #define        Rc      27      /* const temporary */
                     23: #define RF     16      /* ~0 */
                     24: #define RX     17      /* scratch */
                     25: #define AT     18      /* conversion table */
                     26: 
                     27: /*
                     28:  * Instructions
                     29:  */
                     30: /* Inst2a */
                     31: #define        SETHI   0x04
                     32: /* Inst2b */
                     33: #define        BG      0x0A
                     34: /* Inst3 2 */
                     35: #define        ADD     0x00
                     36: #define        SUB     0x04
                     37: #define        AND     0x01
                     38: #define        OR      0x02
                     39: #define        XOR     0x03
                     40: #define        ANDN    0x05
                     41: #define        ORN     0x06
                     42: #define        SUBcc   0x14
                     43: #define        SLL     0x25
                     44: #define        SRL     0x26
                     45: #define        JMPL    0x38
                     46: /* Inst3 3 */
                     47: #define        LD      0x00
                     48: #define        LDUB    0x01
                     49: #define        LDUH    0x02
                     50: #define        ST      0x04
                     51: 
                     52: /*
                     53:  * Generate `a', `size' bits wide, into bit position `shift'.
                     54:  * (to save execution time, the onus is on the caller to make sure that
                     55:  * `a' fits in `size')
                     56:  */
                     57: #define        SM(a,size,shift)        ((a)<<(shift))
                     58: 
                     59: #define        Inst2a(rd,op2,i)        (SM(rd,5,25)|SM(op2,4,22)|SM(i,22,0))
                     60: #define        Inst2b(a,cond,op2,d)    Inst2a(SM(a,1,4)|SM(cond,4,0), op2, d)
                     61: 
                     62: #define        Inst3X(op,rd,op3,rs1)   (SM(op,2,30)|SM(rd,5,25)|SM(op3,6,19)|SM(rs1,5,14))
                     63: #define        Inst3a(op,rd,op3,rs1,i,asi,rs2) (Inst3X(op,rd,op3,rs1)|SM(i,1,13)|SM(asi,8,5)|SM(rs2,5,0))
                     64: #define        Inst3b(op,rd,op3,rs1,i,si)      (Inst3X(op,rd,op3,rs1)|SM(i,1,13)|SM(si,13,0))
                     65: #define        Inst3c(op,rd,op3,rs1,opf,rs2)   (Inst3X(op,rd,op3,rs1)|SM(opf,9,5)|SM(rs2,5,0))
                     66: 
                     67: #define        OpConst(Rdst,Rsrc,op,c)         /* Rdst = Rsrc op c */ \
                     68:                        if(((ulong)(c)) <= 0xFFF) \
                     69:                                *p++ = Inst3b(2,Rdst,op,Rsrc,1,(c)); \
                     70:                        else { \
                     71:                                RConst(Rc,(c)); \
                     72:                                *p++ = Inst3a(2,Rdst,op,Rsrc,0,0,Rc); \
                     73:                        }       
                     74: 
                     75: #define        RConst(Rdst,c)                  /* Rdst = c; c is large */ \
                     76:                        *p++ = Inst2a(Rdst,SETHI,((ulong)(c))>>10); \
                     77:                        *p++ = Inst3b(2,Rdst,OR,Rdst,1,(c)&0x3FF)
                     78: 
                     79: 
                     80: /*
                     81:  * Macros for assembling the operations of the abstract machine.
                     82:  * Each assumes that ulong *p points to the next location where
                     83:  * an instruction should be assembled.
                     84:  * These macros can use RX as a scratch register, but no others.
                     85:  * They can assume RF holds ~0 and R0 holds 0.
                     86:  */
                     87: 
                     88: #define Ofield(c)      *p++ = Inst3a(2,Rs,XOR,Rs,0,0,Rd); \
                     89:                        RConst(Rc,(c)); \
                     90:                        *p++ = Inst3a(2,Rs,AND,Rs,0,0,Rc); \
                     91:                        *p++ = Inst3a(2,Rs,XOR,Rs,0,0,Rd)
                     92: 
                     93: #define Olsha_RsRt     *p++ = Inst3a(2,Rs,SLL,Rt,1,0,sha)
                     94: #define Olshb_RsRt     *p++ = Inst3a(2,Rs,SLL,Rt,1,0,shb)
                     95: #define Olsh_RsRd(c)   *p++ = Inst3a(2,Rs,SLL,Rd,1,0,(c))
                     96: #define Olsh_RtRt(c)   *p++ = Inst3a(2,Rt,SLL,Rt,1,0,(c))
                     97: #define Olsha_RtRt     *p++ = Inst3a(2,Rt,SLL,Rt,1,0,sha)
                     98: #define Olsha_RtRu     *p++ = Inst3a(2,Rt,SLL,Ru,1,0,sha)
                     99: #define Olshb_RtRu     *p++ = Inst3a(2,Rt,SLL,Ru,1,0,shb)
                    100: #define Orsha_RsRt     *p++ = Inst3a(2,Rs,SRL,Rt,1,0,sha)
                    101: #define Orshb_RsRt     *p++ = Inst3a(2,Rs,SRL,Rt,1,0,shb)
                    102: #define Orsha_RtRu     *p++ = Inst3a(2,Rt,SRL,Ru,1,0,sha)
                    103: #define Orshb_RtRu     *p++ = Inst3a(2,Rt,SRL,Ru,1,0,shb)
                    104: #define Oorlsha_RsRt   *p++ = Inst3a(2,RX,SLL,Rt,1,0,sha); \
                    105:                        *p++ = Inst3a(2,Rs,OR,Rs,0,0,RX)
                    106: #define Oorlshb_RsRt   *p++ = Inst3a(2,RX,SLL,Rt,1,0,shb); \
                    107:                        *p++ = Inst3a(2,Rs,OR,Rs,0,0,RX)
                    108: #define Oorlsh_RsRd(c) *p++ = Inst3a(2,RX,SLL,Rd,1,0,(c)); \
                    109:                        *p++ = Inst3a(2,Rs,OR,Rs,0,0,RX)
                    110: #define Oorrsha_RsRt   *p++ = Inst3a(2,RX,SRL,Rt,1,0,sha); \
                    111:                        *p++ = Inst3a(2,Rs,OR,Rs,0,0,RX)
                    112: #define Oorrshb_RsRt   *p++ = Inst3a(2,RX,SRL,Rt,1,0,shb); \
                    113:                        *p++ = Inst3a(2,Rs,OR,Rs,0,0,RX)
                    114: #define Oorrsha_RtRu   *p++ = Inst3a(2,RX,SRL,Ru,1,0,sha); \
                    115:                        *p++ = Inst3a(2,Rt,OR,Rt,0,0,RX)
                    116: #define Oorrshb_RtRu   *p++ = Inst3a(2,RX,SRL,Ru,1,0,shb); \
                    117:                        *p++ = Inst3a(2,Rt,OR,Rt,0,0,RX)
                    118: #define Oor_RsRd       *p++ = Inst3a(2,Rs,OR,Rd,0,0,Rs)
                    119: 
                    120: #define Add_As(c)      OpConst(As,As,ADD,(c))
                    121: 
                    122: #define Add_Ad(c)      OpConst(Ad,Ad,ADD,(c))
                    123: 
                    124: #define Initsd(s,d)    RConst(As,((ulong)(s))); \
                    125:                        RConst(Ad,((ulong)(d)))
                    126: 
                    127: #define Initsh(a,b)
                    128: 
                    129: /* Put all ones in RF */
                    130: #define Extrainit      *p++ = Inst3b(2,RF,ORN,R0,1,0)
                    131: 
                    132: #define Ilabel(c)      RConst(Ri,(c))
                    133: 
                    134: #define Olabel(c)      RConst(Ro,(c))
                    135: 
                    136: #define Iloop(lp)      *p++ = Inst3b(2,Ri,SUBcc,Ri,1,1); \
                    137:                        *p   = Inst2b(0,BG,0x2,((lp)-p)&0x3FFFFF); p++; \
                    138:                        Nop
                    139: 
                    140: #define Oloop(lp)      *p++ = Inst3b(2,Ro,SUBcc,Ro,1,1); \
                    141:                        *p   = Inst2b(0,BG,0x2,((lp)-p)&0x3FFFFF); p++; \
                    142:                        Nop
                    143: 
                    144: #define Orts           *p++ = Inst3b(2,R0,JMPL,15,1,8); \
                    145:                        Nop
                    146: 
                    147: /*
                    148:  * In the predecrement versions, it's as easy to do the decrement afterwards
                    149:  * in the (virtual) delay slot, which will go faster on some versions
                    150:  */
                    151: 
                    152: #define Load_Rs_P      *p++ = Inst3b(3,Rs,LD,As,1,0); *p++ = Inst3b(2,As,ADD,As,1,4)
                    153: #define Load_Rt_P      *p++ = Inst3b(3,Rt,LD,As,1,0); *p++ = Inst3b(2,As,ADD,As,1,4)
                    154: #define Loadzx_Rt_P    *p++ = Inst3b(3,Rt,LD,As,1,0); *p++ = Inst3b(2,As,ADD,As,1,4)
                    155: #define Loador_Rt_P    *p++ = Inst3b(3,Rt,LD,As,1,0); *p++ = Inst3b(2,As,ADD,As,1,4)
                    156: #define Load_Ru_P      *p++ = Inst3b(3,Ru,LD,As,1,0); *p++ = Inst3b(2,As,ADD,As,1,4)
                    157: #define Load_Rd_D(f)   *p++ = Inst3b(3,Rd,LD,As,1,(-4)&0x1FFF); *p++ = Inst3b(2,As,SUB,As,1,4)
                    158: #define Load_Rs_D(f)   *p++ = Inst3b(3,Rs,LD,As,1,(-4)&0x1FFF); *p++ = Inst3b(2,As,SUB,As,1,4)
                    159: #define Load_Rt_D(f)   *p++ = Inst3b(3,Rt,LD,As,1,(-4)&0x1FFF); *p++ = Inst3b(2,As,SUB,As,1,4)
                    160: #define Loadzx_Rt_D(f) *p++ = Inst3b(3,Rt,LD,As,1,(-4)&0x1FFF); *p++ = Inst3b(2,As,SUB,As,1,4)
                    161: #define Load_Rd(f)     *p++ = Inst3b(3,Rd,LD,As,1,0)
                    162: #define Load_Rs(f)     *p++ = Inst3b(3,Rs,LD,As,1,0)
                    163: #define Load_Rt(f)     *p++ = Inst3b(3,Rt,LD,As,1,0)
                    164: #define Loadzx_Rt(f)   *p++ = Inst3b(3,Rt,LD,As,1,0)
                    165: #define Fetch_Rd_P(f)  *p++ = Inst3b(3,Rd,LD,Ad,1,0); *p++ = Inst3b(2,Ad,ADD,Ad,1,4)
                    166: #define Fetch_Rd_D(f)  *p++ = Inst3b(3,Rd,LD,Ad,1,(-4)&0x1FFF); *p++ = Inst3b(2,Ad,SUB,Ad,1,4)
                    167: #define Fetch_Rd(f)    *p++ = Inst3b(3,Rd,LD,Ad,1,0);
                    168: #define Store_Rs_P     *p++ = Inst3b(3,Rs,ST,Ad,1,0); *p++ = Inst3b(2,Ad,ADD,Ad,1,4)
                    169: #define Store_Rs_D     *p++ = Inst3b(3,Rs,ST,Ad,1,(-4)&0x1FFF); *p++ = Inst3b(2,Ad,SUB,Ad,1,4)
                    170: #define Store_Rs       *p++ = Inst3b(3,Rs,ST,Ad,1,0)
                    171: #define Nop            *p++ = Inst3a(2,R0,OR,R0,0,0,R0)
                    172: 
                    173: #define Inittab(t,s)   RConst(AT,((ulong)(t)))
                    174: 
                    175: /* emit code to look up n bits at offset o; table entries are 1<<l bytes long */
                    176: #define Table_RdRt(o,n,l)                                      \
                    177:        tmp = 32-((o)+(n))-(l);                                 \
                    178:        if(tmp >= 0)                                            \
                    179:                *p++ = Inst3a(2,Rd,SRL,Rt,1,0,tmp);             \
                    180:        else if((l) > 0)                                        \
                    181:                *p++ = Inst3a(2,Rd,SLL,Rt,1,0,l);               \
                    182:        else                                                    \
                    183:                *p++ = Inst3a(2,Rd,ADD,Rt,0,0,R0);              \
                    184:        *p++ = Inst3b(2,Rd,AND,Rd,1,((1<<(n))-1)<<(l));         \
                    185:        if(osiz==1) *p++ = Inst3b(3,Rd,LDUB,Rd,0,AT);           \
                    186:        else if(osiz==2) *p++ = Inst3b(3,Rd,LDUH,Rd,0,AT);      \
                    187:        else *p++ = Inst3b(3,Rd,LD,Rd,0,AT);                    \
                    188: 
                    189: #define Table_RsRt(o,n,l)                                      \
                    190:        tmp = 32-((o)+(n))-(l);                                 \
                    191:        *p++ = Inst3a(2,Rs,SRL,Rt,1,0,tmp);                     \
                    192:        if(tmp >= 0)                                            \
                    193:                *p++ = Inst3a(2,Rs,SRL,Rt,1,0,tmp);             \
                    194:        else if((l) > 0)                                        \
                    195:                *p++ = Inst3a(2,Rs,SLL,Rt,1,0,l);               \
                    196:        else                                                    \
                    197:                *p++ = Inst3a(2,Rs,ADD,Rt,0,0,R0);              \
                    198:        if(osiz==1) *p++ = Inst3b(3,Rs,LDUB,Rs,0,AT);           \
                    199:        else if(osiz==2) *p++ = Inst3b(3,Rs,LDUH,Rs,0,AT);      \
                    200:        else *p++ = Inst3b(3,Rs,LD,Rs,0,AT);                    \
                    201: 
                    202: /* emit code to assemble low n bits of Rd into offset o in Rs */
                    203: #define Assemble(o,n)                          \
                    204:        if((o) == 0) {                          \
                    205:                Olsh_RsRd(32-(n));              \
                    206:        } else if((o) == 32-(n)) {              \
                    207:                *p++ = Inst3a(2,Rs,OR,Rs,0,0,Rd); \
                    208:        } else {                                \
                    209:                Oorlsh_RsRd(32-((o)+(n)));      \
                    210:        }
                    211: 
                    212: /* emit code to assemble low n bits of Rd into offset o in Rs.
                    213:    this works by shifting Rd as we go, it only works if
                    214:    the whole word will eventually be filled */
                    215: #define Assemblex(o,n)                         \
                    216:        if((o) == 0) {                          \
                    217:                *p++ = Inst3a(2,Rs,OR,Rd,0,0,R0); \
                    218:        } else {                                \
                    219:                *p++ = Inst3a(2,Rs,SLL,Rs,1,0,n); \
                    220:                *p++ = Inst3a(2,Rs,OR,Rd,0,0,Rs); \
                    221:        }
                    222: 
                    223: #define Execandfree(memstart,onstack)                          \
                    224:        (*(void (*)(void))memstart)();                          \
                    225:        if(!onstack)                                            \
                    226:                bbfree(memstart, (p-memstart) * sizeof(Type));
                    227: 
                    228: #define Emitop                 \
                    229:        p[0] = fi[0];           \
                    230:        p[1] = fi[1];           \
                    231:        p = (Type*)(((char *)p)+fin)
                    232: 
                    233: typedef struct Fstr
                    234: {
                    235:        char    fetchs;
                    236:        char    fetchd;
                    237:        short   n;
                    238:        Type    instr[2];
                    239: } Fstr;
                    240: 
                    241: Fstr   fstr[16] =
                    242: {
                    243: [0]    0,0,4,          /* Zero */
                    244:        { Inst3a(2,Rs,ADD,R0,0,0,R0), 0 },
                    245: 
                    246: [1]    1,1,8,          /* DnorS */
                    247:        { Inst3a(2,Rs,OR,Rs,0,0,Rd), Inst3a(2,Rs,XOR,Rs,0,0,RF) },
                    248: 
                    249: [2]    1,1,4,          /* DandnotS */
                    250:        { Inst3a(2,Rs,ANDN,Rd,0,0,Rs), 0 },
                    251: 
                    252: [3]    1,0,4,          /* notS */
                    253:        { Inst3a(2,Rs,XOR,Rs,0,0,RF), 0 },
                    254: 
                    255: [4]    1,1,4,          /* notDandS */
                    256:        { Inst3a(2,Rs,ANDN,Rs,0,0,Rd), 0 },
                    257: 
                    258: [5]    0,1,4,          /* notD */
                    259:        { Inst3a(2,Rs,XOR,Rd,0,0,RF), 0 },
                    260: 
                    261: [6]    1,1,4,          /* DxorS */
                    262:        { Inst3a(2,Rs,XOR,Rd,0,0,Rs), 0 },
                    263: 
                    264: [7]    1,1,8,          /* DnandS */
                    265:        { Inst3a(2,Rs,AND,Rd,0,0,Rs), Inst3a(2,Rs,XOR,Rs,0,0,RF) },
                    266: 
                    267: [8]    1,1,4,          /* DandS */
                    268:        { Inst3a(2,Rs,AND,Rd,0,0,Rs), 0 },
                    269: 
                    270: [9]    1,1,8,          /* DxnorS */
                    271:        { Inst3a(2,Rs,XOR,Rd,0,0,Rs), Inst3a(2,Rs,XOR,Rs,0,0,RF) },
                    272: 
                    273: [10]   0,1,4,          /* D */
                    274:        { Inst3a(2,Rs,ADD,Rd,0,0,R0), 0 },
                    275: 
                    276: [11]   1,1,4,          /* DornotS */
                    277:        { Inst3a(2,Rs,ORN,Rd,0,0,Rs), 0 },
                    278: 
                    279: [12]   1,0,0,          /* S */
                    280:        {0, 0},
                    281: 
                    282: [13]   1,1,4,          /* notDorS */
                    283:        { Inst3a(2,Rs,ORN,Rs,0,0,Rd), 0 },
                    284: 
                    285: [14]   1,1,4,          /* DorS */
                    286:        { Inst3a(2,Rs,OR,Rd,0,0,Rs), 0 },
                    287: 
                    288: [15]   0,0,4,          /* F */
                    289:        { Inst3a(2,Rs,OR,R0,0,0,RF), 0 },
                    290: };
                    291: 
                    292: #include "tabs.h"
                    293: static uchar *tabs[4][4] =
                    294: {
                    295:        {            0, (uchar*)tab01, (uchar*)tab02, (uchar*)tab03},
                    296:        {(uchar*)tab10,             0, (uchar*)tab12, (uchar*)tab13},
                    297:        {(uchar*)tab20, (uchar*)tab21,             0, (uchar*)tab23},
                    298:        {(uchar*)tab30, (uchar*)tab31, (uchar*)tab32,             0},
                    299: };
                    300: 
                    301: static uchar tabosiz[4][4] = /* size in bytes of entries */
                    302: {
                    303:        { 0, 2, 4, 4},
                    304:        { 1, 0, 2, 4},
                    305:        { 1, 1, 0, 2},
                    306:        { 1, 1, 1, 0},
                    307: };
                    308: 
                    309: enum {
                    310:        Progmax = 1000,         /* max number of bytes in a bitblt prog */
                    311:        Progmaxnoconv = 70,     /* max number of Type units when no conversion */
                    312: };
                    313: 
                    314: 
                    315: #ifdef TEST
                    316: void
                    317: prprog(void)
                    318: {
                    319:        abort();        /* use db */
                    320: }
                    321: 
                    322: #endif

unix.superglobalmegacorp.com

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