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