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

1.1       root        1: /*
                      2:  * See the comments at the beginning of bb.c and bbc.h
                      3:  * for an outline of how this bitblt works
                      4:  
                      5:  * The VGA screen on the 386 has an awful bit/byte order:
                      6:  * the high order bit of a byte is leftmost, but the low
                      7:  * order byte of a word is leftmost.
                      8:  * This is a totally littleendian bitblt, so the bytes will
                      9:  * have to be bit-reversed before putting them on the screen.
                     10:  */
                     11: typedef        uchar   Type;
                     12: 
                     13: /*
                     14:  * Registers:
                     15:  */
                     16: #define As     6       /* ESI */
                     17: #define Ad     7       /* EDI */
                     18: #define        Rs      0       /* EAX: FIELD works better with this here */
                     19: #define        Rd      3       /* EBX */
                     20: #define Rt     2       /* EDX */
                     21: #define Ru     1       /* ECX */
                     22: #define RX     5       /* EBP */
                     23: #define SP     4       /* ESP */
                     24: /* Ri is top-of-stack, if needed */
                     25: /* Ro is second-top-of-stack, if needed */
                     26:  
                     27: /*
                     28:  * Macros for assembling 386 instructions
                     29:  */
                     30: #define MODRM(mod,rm,reg)      (((mod)<<6)|((reg)<<3)|(rm))
                     31: #define SIB(ss,ind,base)       (((ss)<<6)|((ind)<<3)|(base))
                     32: #define RMR(rm,reg)            MODRM(3,rm,reg)
                     33: #define        IRMR(rm,reg)            MODRM(0,rm,reg)
                     34: #define DB(b1,b2,b3,b4)                ((b1)|((b2)<<8)|((b3)<<16)|((b4)<<24))
                     35: #define SB(b1,b2)              ((b1)|((b2)<<8))
                     36: 
                     37: #define OR(src,dst)            SB(0x0B, RMR(src,dst))
                     38: #define XOR(src,dst)           SB(0x31, RMR(dst,src))
                     39: #define AND(src,dst)           SB(0x21, RMR(dst,src))
                     40: #define NOT(r)                 SB(0xF7, RMR(r,2))
                     41: #define MOV(src,dst)           SB(0x89, RMR(dst,src))
                     42: 
                     43: #define Immd(v)                        *(long*)p = (long)(v); p += 4
                     44: #define Immdb(b1,b2,b3,b4)     Immd(DB(b1,b2,b3,b4))
                     45: #define Imms(v)                        *(short*)p = (v); p += 2
                     46: #define        Immsb(b1,b2)            Imms(SB(b1,b2))
                     47: 
                     48: #define Load(areg,dst)         Immsb(0x8B, IRMR(areg,dst))
                     49: #define Store(src,areg)                Immsb(0x89, IRMR(areg,src))
                     50: #define Mov(src,dst)           Imms(MOV(src,dst))
                     51: #define Movd(v,dst)            *p++ = (0xB8 + (dst)); Immd(v)
                     52: #define Imov(a,i,r)            *p++ = 0x8B; Immsb(IRMR(4,r),SIB(2,i,5)); Immd(a)
                     53: #define Or(src,dst)            Imms(OR(src,dst))
                     54: #define Xor(src,dst)           Imms(XOR(src,dst))
                     55: #define And(src,dst)           Imms(AND(src,dst))
                     56: #define Andd(v,dst)            if(dst==Rs) {\
                     57:                                        *p++ = 0x25;\
                     58:                                } else {\
                     59:                                        Immsb(0x81, RMR(dst,4));\
                     60:                                }\
                     61:                                Immd(v)
                     62: #define Not(r)                 Imms(NOT(r))
                     63: #define Inc(r)                 *p++ = (0x40 + (r))
                     64: #define Dec(r)                 *p++ = (0x48 + (r))
                     65: #define Decsp                  Immsb(0xFF, IRMR(4,1)); *p++ = SIB(0,4,4)
                     66: #define Shl(r,sh)              Immsb(0xC1, RMR(r,4)); *p++ = (sh)
                     67: #define Shr(r,sh)              Immsb(0xC1, RMR(r,5)); *p++ = (sh)
                     68: #define Addd(v,r)              Immsb(0x81, RMR(r,0)); Immd(v)
                     69: #define Addbsx(v,r)            Immsb(0x83, RMR(r,0)); *p++ = v
                     70: #define Addsp(v)               Immsb(0x83, RMR(4,0)); *p++ = v
                     71: #define Pushd(v)               *p++ = 0x68; Immd(v)
                     72: #define Loop(d)                        *p = 0xE2; *(p+1) = d; p += 2
                     73: #define Jmp8(d)                        *p = 0xEB; *(p+1) = d; p += 2
                     74: #define Jmp(d)                 *p++ = 0xE9; Immd(d)
                     75: #define Jg8(d)                 *p = 0x7F; *(p+1) = d; p += 2
                     76: #define Jle8(d)                        *p = 0x7E; *(p+1) = d; p += 2
                     77: 
                     78: #define Ofield(c)      Xor(Rd,Rs); Andd(c,Rs); Xor(Rd,Rs)
                     79: #define Olsha_RsRt     Mov(Rt,Rs); Shr(Rs,sha)
                     80: #define Olshb_RsRt     Mov(Rt,Rs); Shr(Rs,shb)
                     81: #define Olsh_RsRd(sh)  Mov(Rd,Rs); Shr(Rs,sh)
                     82: #define Olsh_RtRt(sh)  Shr(Rt,sh)
                     83: #define Olsha_RtRt     Shr(Rt,sha)
                     84: #define Olsha_RtRu     Mov(Ru,Rt); Shr(Rt,sha)
                     85: #define Olshb_RtRu     Mov(Ru,Rt); Shr(Rt,shb)
                     86: #define Orsha_RsRt     Mov(Rt,Rs); Shl(Rs,sha)
                     87: #define Orshb_RsRt     Mov(Rt,Rs); Shl(Rs,shb)
                     88: #define Orsha_RtRu     Mov(Ru,Rt); Shl(Rt,sha)
                     89: #define Orshb_RtRu     Mov(Ru,Rt); Shl(Rt,shb)
                     90: #define Oorlsha_RsRt   Mov(Rt,RX); Shr(RX,sha); Or(RX,Rs)
                     91: #define Oorlshb_RsRt   Mov(Rt,RX); Shr(RX,shb); Or(RX,Rs)
                     92: #define Oorlsh_RsRd(sh)        Mov(Rd,RX); Shr(RX,sh); Or(RX,Rs)
                     93: #define Oorrsha_RsRt   Mov(Rt,RX); Shl(RX,sha); Or(RX,Rs)
                     94: #define Oorrshb_RsRt   Mov(Rt,RX); Shl(RX,shb); Or(RX,Rs)
                     95: #define Oorrsha_RtRu   Mov(Ru,RX); Shl(RX,sha); Or(RX,Rt)
                     96: #define Oorrshb_RtRu   Mov(Ru,RX); Shl(RX,shb); Or(RX,Rt)
                     97: #define Oor_RsRd       Or(Rd,Rs)
                     98: #define Add_As(v)      Addd(v,As)
                     99: #define Add_Ad(v)      Addd(v,Ad)
                    100: #define Initsd(s,d)    Movd(s,As); Movd(d,Ad)
                    101: #define Ilabel(c)      Pushd(c)
                    102: #define Olabel(c)      Pushd(c)
                    103: #define Iloop(lp)      Decsp;                          \
                    104:                        tmp = (lp)-(p+2);               \
                    105:                        if(tmp > -128) {                \
                    106:                                Jg8(tmp);               \
                    107:                        } else {                        \
                    108:                                Jle8(5);                \
                    109:                                tmp = (lp) - (p+5);     \
                    110:                                Jmp(tmp);               \
                    111:                        }                               \
                    112:                        Addsp(4)
                    113: #define Oloop(lp)      Decsp;                          \
                    114:                        tmp = (lp)-(p+2);               \
                    115:                        if(tmp > -128) {                \
                    116:                                Jg8(tmp);               \
                    117:                        } else {                        \
                    118:                                Jle8(5);                \
                    119:                                tmp = (lp) - (p+5);     \
                    120:                                Jmp(tmp);               \
                    121:                        }                               \
                    122:                        Addsp(4)
                    123: #define Orts           *p++ = 0xC3
                    124: /* load */
                    125: #define Load_Rs_P      Load(As,Rs); Addbsx(4,As)
                    126: #define Load_Rt_P      Load(As,Rt); Addbsx(4,As)
                    127: #define Loadzx_Rt_P    Load(As,Rt); Addbsx(4,As)
                    128: #define Loador_Rt_P    Load(As,Rt); Addbsx(4,As)
                    129: #define Load_Ru_P      Load(As,Ru); Addbsx(4,As)
                    130: #define Load_Rd_D(f)   Addbsx(-4,As); Load(As,Rd)
                    131: #define Load_Rs_D(f)   Addbsx(-4,As); Load(As,Rs)
                    132: #define Load_Rt_D(f)   Addbsx(-4,As); Load(As,Rt)
                    133: #define Loadzx_Rt_D(f) Addbsx(-4,As); Load(As,Rt)
                    134: #define Load_Rd(f)     Load(As,Rd)
                    135: #define Load_Rs(f)     Load(As,Rs)
                    136: #define Load_Rt(f)     Load(As,Rt)
                    137: #define Loadzx_Rt(f)   Load(As,Rt)
                    138: /* fetch */
                    139: #define Fetch_Rd_P(f)  Load(Ad,Rd); Addbsx(4,Ad)
                    140: #define Fetch_Rd_D(f)  Addbsx(-4,Ad); Load(Ad,Rd)
                    141: #define Fetch_Rd(f)    Load(Ad,Rd)
                    142: /* store */
                    143: #define Store_Rs_P     Store(Rs,Ad); Addbsx(4,Ad)
                    144: #define Store_Rs_D     Addbsx(-4,Ad); Store(Rs,Ad)
                    145: #define Store_Rs       Store(Rs,Ad)
                    146: 
                    147: #define Inittab(t,s)
                    148: #define Initsh(a,b)
                    149: 
                    150: /* emit code to look up n bits of Rt at offset o, answer ulong in Rd */
                    151: #define Table_RdRt(o,n,l)              \
                    152:        Mov(Rt,Rd);                     \
                    153:        if(o) { Shr(Rd,(o)); }          \
                    154:        Andd(((1<<(n))-1),Rd);          \
                    155:        Imov(tab,Rd,Rd)
                    156: 
                    157: #define Table_RsRt(o,n,l)              \
                    158:        Mov(Rt,Rs);                     \
                    159:        if(o) { Shr(Rs,o); }            \
                    160:        Andd(((1<<(n))-1),Rs);          \
                    161:        Imov(tab,Rs,Rs)
                    162: 
                    163: /* emit code to assemble high n bits of Rd into offset o in Rs */
                    164: #define Assemble(o,n)                          \
                    165:        if((o) == 0) {                          \
                    166:                Olsh_RsRd(32-(n));              \
                    167:        } else if((o) == 32-(n)) {              \
                    168:                Or(Rd,Rs);                      \
                    169:        } else {                                \
                    170:                Oorlsh_RsRd(32-((o)+(n)));      \
                    171:        }
                    172: 
                    173: /* concept of shifting-as-you-go doesn't work when filling from low end */
                    174: #define Assemblex(o,n) Assemble(o,n)
                    175: 
                    176: #define Nop
                    177: 
                    178: #ifdef TEST
                    179: #define Extrainit              \
                    180:        Movd(lrand(),Rs);       \
                    181:        Movd(lrand(),Rd);       \
                    182:        Movd(lrand(),Rt);       \
                    183:        Movd(lrand(),Ru);       \
                    184:        Movd(lrand(),RX)
                    185: #else
                    186: #define Extrainit
                    187: #endif
                    188: 
                    189: #define Execandfree(memstart,onstack)                          \
                    190:        (*(void (*)(void))memstart)();                          \
                    191:        if(!onstack)                                            \
                    192:                bbfree(memstart, (p-memstart) * sizeof(Type));
                    193: 
                    194: /* emit code seq at fi (at most 3 shorts) */
                    195: #define Emitop                                         \
                    196:        *(long *)p = *(long *)fi;                       \
                    197:        *(short *)(p+4) = *(short *)(((char *)fi)+4);   \
                    198:        p = (Type*)(((char *)p)+fin)
                    199: 
                    200: typedef struct Fstr
                    201: {
                    202:        short   fetchs;
                    203:        short   fetchd;
                    204:        int     n;
                    205:        short   instr[4];
                    206: } Fstr;
                    207: 
                    208: Fstr   fstr[16] =
                    209: {
                    210: [0]    0,0,2,          /* Zero */
                    211:        { XOR(Rs,Rs), 0, 0, 0 },
                    212: 
                    213: [1]    1,1,4,          /* DnorS */
                    214:        { OR(Rd,Rs), NOT(Rs), 0, 0},
                    215: 
                    216: [2]    1,1,4,          /* DandnotS */
                    217:        { NOT(Rs), AND(Rd,Rs), 0, 0},
                    218: 
                    219: [3]    1,0,2,          /* notS */
                    220:        { NOT(Rs), 0, 0, 0},
                    221: 
                    222: [4]    1,1,6,          /* notDandS */
                    223:        { NOT(Rs), OR(Rd,Rs), NOT(Rs), 0},
                    224: 
                    225: [5]    0,1,4,          /* notD */
                    226:        { MOV(Rd,Rs), NOT(Rs), 0, 0},
                    227: 
                    228: [6]    1,1,2,          /* DxorS */
                    229:        { XOR(Rd,Rs), 0, 0, 0},
                    230: 
                    231: [7]    1,1,4,          /* DnandS */
                    232:        { AND(Rd,Rs), NOT(Rs), 0, 0},
                    233: 
                    234: [8]    1,1,2,          /* DandS */
                    235:        { AND(Rd,Rs), 0, 0, 0},
                    236: 
                    237: [9]    1,1,4,          /* DxnorS */
                    238:        { XOR(Rd,Rs), NOT(Rs), 0, 0},
                    239: 
                    240: [10]   0,1,2,          /* D */
                    241:        { MOV(Rd,Rs), 0, 0, 0},
                    242: 
                    243: [11]   1,1,4,          /* DornotS */
                    244:        { NOT(Rs), OR(Rd,Rs), 0, 0},
                    245: 
                    246: [12]   1,0,0,          /* S */
                    247:        { 0, 0, 0, 0},
                    248: 
                    249: [13]   1,1,6,          /* notDorS */
                    250:        { NOT(Rs), AND(Rd,Rs), NOT(Rs), 0},
                    251: 
                    252: [14]   1,1,2,          /* DorS */
                    253:        { OR(Rd,Rs), 0, 0, 0},
                    254: 
                    255: [15]   0,0,4,          /* F */
                    256:        { XOR(Rs,Rs), NOT(Rs), 0, 0},
                    257: };
                    258: 
                    259: #include "tabs.h"
                    260: 
                    261: static uchar *tabs[4][4] =
                    262: {
                    263:        {             0, (uchar*)tab01l, (uchar*)tab02l, (uchar*)tab03l},
                    264:        {(uchar*)tab10l,              0, (uchar*)tab12l, (uchar*)tab13l},
                    265:        {(uchar*)tab20l, (uchar*)tab21l,              0, (uchar*)tab23l},
                    266:        {(uchar*)tab30l, (uchar*)tab31l, (uchar*)tab32l,              0},
                    267: };
                    268: 
                    269: static uchar tabosiz[4][4] = /* size in bytes of entries */
                    270: {
                    271:        { 0, 2, 4, 4},
                    272:        { 1, 0, 2, 4},
                    273:        { 1, 1, 0, 2},
                    274:        { 1, 1, 1, 0},
                    275: };
                    276: 
                    277: enum {
                    278:        Progmax = 3000,         /* max number of bytes in a bitblt prog */
                    279:        Progmaxnoconv = 200,    /* max number when not converting */
                    280: };
                    281: 
                    282: #ifdef TEST
                    283: void
                    284: prprog(void)
                    285: {
                    286:        abort();        /* use db */
                    287: }
                    288: 
                    289: void
                    290: bbexec(void (*memstart)(void), int len, int onstack)
                    291: {
                    292:        memstart();
                    293:        if(!onstack)
                    294:                bbfree(memstart, len);
                    295: }
                    296: 
                    297: #endif

unix.superglobalmegacorp.com

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