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

1.1       root        1: typedef        long    Type;
                      2: 
                      3: /*
                      4:  * This C version compiles for an abstract machine, and an interpreter
                      5:  * is used to execute the program.  The program consists of opcdoes
                      6:  * from the following enumeration.  Some opcodes take arguments: arguments
                      7:  * are put in longs immediately following the opcode.
                      8:  *
                      9:  * Here is a description of the abstract machine.  The `word' size is
                     10:  * WBITS bits, usually 32.
                     11:  *
                     12:  * word registers:
                     13:  *     Rs      holds word from source bitmap, then a word from
                     14:  *             source bitmap that may straddle a word boundary,
                     15:  *             and finally, result of doing the Rs op Rd operation,
                     16:  *             prior to storing in destination bitmap
                     17:  *     Rd      holds word from destination bitmap
                     18:  *     Rt      used to hold some bits from a source bitmap that will
                     19:  *             be used to make a properly aligned source word later
                     20:  *     Ru      an additional register used in converting bitblts to
                     21:  *             hold some source bits (to avoid the need to fetch a
                     22:  *             source word more than once)
                     23:  *     Ri      inner loop count: how many more words in row
                     24:  *     Ro      outer loop count: how many more rows
                     25:  *
                     26:  * address registers:
                     27:  *     As      address in source bitmap
                     28:  *     Ad      address in destination bitmap
                     29:  *     AT      address of a conversion table
                     30:  *
                     31:  * small constant registers (These don't change after they are set.
                     32:  *             In most implementations, these values are
                     33:  *             not in explicit registers, but rather, the
                     34:  *             values are encoded in the instructions that use them.)
                     35:  *
                     36:  *      sha    shift value a
                     37:  *     shb     shift value b
                     38:  *     osiz    number of bytes in conversion table entries
                     39:  *
                     40:  * operations:
                     41:  *   The operations of the abstract machine are the following:
                     42:  *   enumeration.  Many of them take an argument or two.
                     43:  *
                     44:  *     field(m): replace Rs with a value that has Rs contents where
                     45:  *             the mask m has 1's, and has Rd contents where mask m
                     46:  *             0's.
                     47:  *
                     48:  *     [lr]sh_RxRy(c): replace Rx with Ry shifted logically left
                     49:  *             or right by c (for various Rx, Ry)
                     50:  *
                     51:  *     [lr]sh[ab]_RxRy: replace Rx with Ry shifted logically left
                     52:  *             or right by value of sha or shb (for various Rx, Ry)
                     53:  *
                     54:  *     [lr]shb_RxRy: replace Rx with Ry shifted logically left
                     55:  *             or right by value of shb (for various Rx, Ry)
                     56:  *
                     57:  *     or[lr]sh_RxRy(c): OR into Rx the value of Ry shifted logically
                     58:  *             left or right by c (for various Rx, Ry)
                     59:  *
                     60:  *     or[lr]sh[ab]_RxRy: OR into Rx the value of Ry shifted logically
                     61:  *             left or right by value of sha or shb (for various Rx, Ry)
                     62:  *
                     63:  *     add_A[sd](c): add the argument number of bytes to the address in
                     64:  *             As or Ad
                     65:  *
                     66:  *     or_RsRd: replace Rs with Rs|Rd
                     67:  *
                     68:  *     Initsd(s,d): init As and Ad from the given arguments
                     69:  *
                     70:  *     [io]label(c): set Ri or Ro to c
                     71:  *
                     72:  *     [io]loop(a): decrement Ri or Ro, and if it is still > 0, go to
                     73:  *             address a
                     74:  *
                     75:  *     rts:    return to caller
                     76:  *
                     77:  *     load_Rx: load Rx with value at address in As (various Rx).
                     78:  *             [On machines where the real machine registers are
                     79:  *              bigger than WBITS, the load_ operations need
                     80:  *              can do whatever they like with the upper bits of
                     81:  *              the register.  There is also a need for some
                     82:  *              loadzx_ operations, which must fill the upper bits
                     83:  *              with zeros, and loador_ operations which must leave
                     84:  *              the high order bits alone, but can assume that the
                     85:  *              low WBITS bits are zero.]
                     86:  *
                     87:  *     load_Rx_P: like OLoad_Rx, then postincrement As by one word
                     88:  *
                     89:  *     load_Rx_D: like OLoad_Rx, but predecrement As by one word first
                     90:  *
                     91:  *     fetch_Rd, OFetch_Rd_P, OFetch_Rd_D: like Loads, but use Ad
                     92:  *             as the address register (and all fetches go to Rd)
                     93:  *
                     94:  *     store_Rs, OStore_Rs_P, OStore_Rs_D: like Loads, but store the
                     95:  *             word in Rs into memory, using address in Ad
                     96:  *
                     97:  *     inittab(a,s): set At to a, and osiz to s.
                     98:  *
                     99:  *     initsh(a,b): set sha to a, shb to b
                    100:  *
                    101:  *     table_R[ds]Rt(o,n,l): starting at offset o in Rt (high order bit of word
                    102:  *             is offset 0), take n bits, and use it to look up a (1<<l) byte
                    103:  *             entry in table AT, putting answer in Rd or Rs.  If WBITS is less
                    104:  *             than the real register size, the upper bits must be zeroed.
                    105:  *             [It is guaranteed that (1<<l) == osiz, so l can be ignored.]
                    106:  *
                    107:  *     assemble(o,n): move low n bits of Rd into offset o in Rs.
                    108:  *             Can assume that high bits of Rd are zero, and target field
                    109:  *             of Rs is zero if offset != 0
                    110:  *
                    111:  *     assemblex(o,n): if o is 0, copy Rd to Rs; else shift Rs left n
                    112:  *             and OR Rd into it. [This will give the same effect as
                    113:  *             assemble, because it will be used in a sequence that
                    114:  *             builds a whole word, such as: assemblex(0,16), assemblex(16,16)
                    115:  *
                    116:  *     Ozero, ODnorS, etc.: replace Rs with value of Rs op Rd, where
                    117:  *             op is one of the 16 bitblt opcodes
                    118:  */
                    119: enum
                    120: {
                    121:        field,          /* arg = field mask */
                    122:        lsha_RsRt,
                    123:        lshb_RsRt,
                    124:        lsh_RsRd,       /* arg = shift amount */
                    125:        lsh_RtRt,       /* arg = shift amount */
                    126:        lsha_RtRt,
                    127:        lsha_RtRu,
                    128:        lshb_RtRu,
                    129:        rsha_RsRt,
                    130:        rshb_RsRt,
                    131:        rsha_RtRu,
                    132:        rshb_RtRu,
                    133:        orlsha_RsRt,
                    134:        orlshb_RsRt,
                    135:        orlsh_RsRd,     /* arg = shift amount */
                    136:        orrsha_RsRt,
                    137:        orrshb_RsRt,
                    138:        orrsha_RtRu,
                    139:        orrshb_RtRu,
                    140:        or_RsRd,
                    141:        add_As,         /* arg = add amount */
                    142:        add_Ad,         /* arg = add amount */
                    143:        initsd,         /* arg1 = value for As; arg2 = value for Ad */
                    144:        ilabel,         /* arg = inner loop count value for Ri */
                    145:        olabel,         /* arg = outer loop count value for Ro */
                    146:        iloop,          /* arg = pointer to beginning of inner loop */
                    147:        oloop,          /* arg = pointer to beginning of outer loop */
                    148:        rts,
                    149:        load_Rs_P,
                    150:        load_Rt_P,
                    151:        load_Ru_P,
                    152:        load_Rd_D,
                    153:        load_Rs_D,
                    154:        load_Rt_D,
                    155:        load_Rd,
                    156:        load_Rs,
                    157:        load_Rt,
                    158:        fetch_Rd_P,
                    159:        fetch_Rd_D,
                    160:        fetch_Rd,
                    161:        store_Rs_P,
                    162:        store_Rs_D,
                    163:        store_Rs,
                    164:        inittab,        /* arg1 = table addr; arg2 = entry size (bytes) */
                    165:        initsh,         /* arg1 = shift amount a, arg2 = shift amount b */
                    166:        table_RdRt,     /* arg1 = offset, arg2 = nbits */
                    167:        table_RsRt,     /* arg1 = offset, arg2 = nbits */
                    168:        assemble,       /* arg1 = offset, arg2 = nbits */
                    169:        assemblex,      /* arg1 = offset, arg2 = nbits */
                    170:        Ozero,
                    171:        ODnorS,
                    172:        ODandnotS,
                    173:        OnotS,
                    174:        OnotDandS,
                    175:        OnotD,
                    176:        ODxorS,
                    177:        ODnandS,
                    178:        ODandS,
                    179:        ODxnorS,
                    180:        OD,
                    181:        ODornotS,
                    182:        OnotDorS,
                    183:        ODorS,
                    184:        OF,
                    185: };
                    186: 
                    187: /*
                    188:  * Macros for assembling the operations of the abstract machine.
                    189:  * Each assumes that Type *p points to the next location where
                    190:  * an instruction should be assembled.  The macros may also make
                    191:  * use of these other variable values:
                    192:  *
                    193:  *     tab     value of AT register in abstract machine
                    194:  *     osiz    value of osiz register in abstract machine
                    195:  *     sha     value of sha register in abstract machine
                    196:  *     shb     value of shb register in abstract machine
                    197:  *
                    198:  * Furthermore, there is a long called tmp which can be used for
                    199:  * the duration of any macro.
                    200:  *
                    201:  * For the most part, the macros required are the same as the
                    202:  * operations in the abstract machine (without a leading O,
                    203:  * or with a lowercase initial letter).  However, instead of
                    204:  * macros for the bitblt opcodes Ozero, ..., OF, there is a
                    205:  * macro called Emitop, which can use implicit arguments
                    206:  * fi and fin (see Emitop, below).
                    207:  *
                    208:  * Some of the load macros take an argument f, which will be 1
                    209:  * if the result of the load will be used by the next instruction.
                    210:  * (Some architectures will require a Noop to be emitted when
                    211:  * f is 1.)
                    212:  *
                    213:  * Finally, two other required macros are Extrainit, which can
                    214:  * be used to do any implementation-specific initialization,
                    215:  * and Execandfree(start,onstack), which must actually execute
                    216:  * the compiled program and free the memory.  If onstack is
                    217:  * true, the program was compiled into a local array, so no
                    218:  * memory need be freed.  Otherwise, the space was obtained with
                    219:  * bbmalloc, and must be freed by bbfree.
                    220:  */
                    221: 
                    222: #define Ofield(c)      *p++ = field; *p++ = (c)
                    223: #define Olsha_RsRt     *p++ = lsha_RsRt
                    224: #define Olshb_RsRt     *p++ = lshb_RsRt
                    225: #define Olsh_RsRd(c)   *p++ = lsh_RsRd; *p++ = (c)
                    226: #define Olsh_RtRt(c)   *p++ = lsh_RtRt; *p++ = (c)
                    227: #define Olsha_RtRt     *p++ = lsha_RtRt
                    228: #define Olsha_RtRu     *p++ = lsha_RtRu
                    229: #define Olshb_RtRu     *p++ = lshb_RtRu
                    230: #define Orsha_RsRt     *p++ = rsha_RsRt
                    231: #define Orshb_RsRt     *p++ = rshb_RsRt
                    232: #define Orsha_RtRu     *p++ = rsha_RtRu
                    233: #define Orshb_RtRu     *p++ = rshb_RtRu
                    234: #define Oorlsha_RsRt   *p++ = orlsha_RsRt
                    235: #define Oorlshb_RsRt   *p++ = orlshb_RsRt
                    236: #define Oorlsh_RsRd(c) *p++ = orlsh_RsRd; *p++ = (c)
                    237: #define Oorrsha_RsRt   *p++ = orrsha_RsRt
                    238: #define Oorrshb_RsRt   *p++ = orrshb_RsRt
                    239: #define Oorrsha_RtRu   *p++ = orrsha_RtRu
                    240: #define Oorrshb_RtRu   *p++ = orrshb_RtRu
                    241: #define Oor_RsRd       *p++ = or_RsRd
                    242: #define Add_As(c)      *p++ = add_As; *p++ = (c)
                    243: #define Add_Ad(c)      *p++ = add_Ad; *p++ = (c)
                    244: #define Initsd(s,d)    *p++ = initsd; *p++ = ((ulong)(s)); *p++ = ((ulong)(d))
                    245: #define Initsh(a,b)    *p++ = initsh; *p++ = (a); *p++ = (b)
                    246: #define Extrainit
                    247: #define Ilabel(c)      *p++ = ilabel; *p++ = (c)
                    248: #define Olabel(c)      *p++ = olabel; *p++ = (c)
                    249: #define Iloop(lp)      *p++ = iloop; *p++ = ((ulong)(lp))
                    250: #define Oloop(lp)      *p++ = oloop; *p++ = ((ulong)(lp))
                    251: #define Orts           *p++ = rts
                    252: #define Load_Rs_P      *p++ = load_Rs_P
                    253: #define Load_Rt_P      *p++ = load_Rt_P
                    254: #define Loadzx_Rt_P    *p++ = load_Rt_P
                    255: #define Loador_Rt_P    *p++ = load_Rt_P
                    256: #define Load_Ru_P      *p++ = load_Ru_P
                    257: #define Load_Rd_D(f)   *p++ = load_Rd_D
                    258: #define Load_Rs_D(f)   *p++ = load_Rs_D
                    259: #define Load_Rt_D(f)   *p++ = load_Rt_D
                    260: #define Loadzx_Rt_D(f) *p++ = load_Rt_D
                    261: #define Load_Rd(f)     *p++ = load_Rd
                    262: #define Load_Rs(f)     *p++ = load_Rs
                    263: #define Load_Rt(f)     *p++ = load_Rt
                    264: #define Loadzx_Rt(f)   *p++ = load_Rt
                    265: #define Fetch_Rd_P(f)  *p++ = fetch_Rd_P
                    266: #define Fetch_Rd_D(f)  *p++ = fetch_Rd_D
                    267: #define Fetch_Rd(f)    *p++ = fetch_Rd
                    268: #define Store_Rs_P     *p++ = store_Rs_P
                    269: #define Store_Rs_D     *p++ = store_Rs_D
                    270: #define Store_Rs       *p++ = store_Rs
                    271: #define Nop
                    272: #define Inittab(t,s)   *p++ = inittab; *p++ = ((ulong)(t)); *p++ = (s)
                    273: #define Table_RdRt(o,n,l) *p++ = table_RdRt; *p++ = (o); *p++ = (n)
                    274: #define Table_RsRt(o,n,l) *p++ = table_RsRt; *p++ = (o); *p++ = (n)
                    275: #define Assemble(o,n)  *p++ = assemble; *p++ = (o); *p++ = (n)
                    276: #define Assemblex(o,n) *p++ = assemble; *p++ = (o); *p++ = (n)
                    277: 
                    278: #define Execandfree(memstart,onstack)                          \
                    279:        interpret(memstart);                                    \
                    280:        if(!onstack)                                            \
                    281:                bbfree(memstart, (p-memstart) * sizeof(Type));
                    282: 
                    283: 
                    284: /*
                    285:  * Emitop can assume that fi points at &fstr[op].instr, and
                    286:  * that fin contains fstr[op].n, where op is the desired
                    287:  * bitblt opcode as declared in gnot.h
                    288:  */
                    289: 
                    290: #define Emitop if(fin) *p++ = *fi;
                    291: 
                    292: typedef struct Fstr
                    293: {
                    294:        char    fetchs;
                    295:        char    fetchd;
                    296:        short   n;
                    297:        Type    instr[1];
                    298: } Fstr;
                    299: 
                    300: Fstr   fstr[16] =
                    301: {
                    302: [0]    0,0,1,          /* Zero */
                    303:        {Ozero},
                    304: 
                    305: [1]    1,1,1,          /* DnorS */
                    306:        {ODnorS},
                    307: 
                    308: [2]    1,1,1,          /* DandnotS */
                    309:        {ODandnotS},
                    310: 
                    311: [3]    1,0,1,          /* notS */
                    312:        {OnotS},
                    313: 
                    314: [4]    1,1,1,          /* notDandS */
                    315:        {OnotDandS},
                    316: 
                    317: [5]    0,1,1,          /* notD */
                    318:        {OnotD},
                    319: 
                    320: [6]    1,1,1,          /* DxorS */
                    321:        {ODxorS},
                    322: 
                    323: [7]    1,1,1,          /* DnandS */
                    324:        {ODnandS},
                    325: 
                    326: [8]    1,1,1,          /* DandS */
                    327:        {ODandS},
                    328: 
                    329: [9]    1,1,1,          /* DxnorS */
                    330:        {ODxnorS},
                    331: 
                    332: [10]   0,1,1,          /* D */
                    333:        {OD},
                    334: 
                    335: [11]   1,1,1,          /* DornotS */
                    336:        {ODornotS},
                    337: 
                    338: [12]   1,0,0,          /* S */
                    339:        {0},
                    340: 
                    341: [13]   1,1,1,          /* notDorS */
                    342:        {OnotDorS},
                    343: 
                    344: [14]   1,1,1,          /* DorS */
                    345:        {ODorS},
                    346: 
                    347: [15]   0,0,1,          /* F */
                    348:        {OF},
                    349: };
                    350: 
                    351: #include "tabs.h"
                    352: 
                    353: enum {
                    354:        Progmax = 800,          /* max number of words in a bitblt prog */
                    355:        Progmaxnoconv = 50,     /* max number of words when no conversion */
                    356: };
                    357: 
                    358: static void
                    359: interpret(Type *pc)
                    360: {
                    361:        ulong *As, *Ad;
                    362:        ulong Rs, Rd, Rt, Ru;
                    363:        long Ri, Ro;
                    364:        uchar *AT;
                    365:        int osiz, sha, shb, tmp;
                    366: 
                    367: #ifdef TEST
                    368:        ulong *Aslow, *Ashigh, *Adlow, *Adhigh;
                    369:        void prprog(void);
                    370: 
                    371:        Rs = lrand();
                    372:        Rd = lrand();
                    373:        Rt = lrand();
                    374:        Ru = lrand();
                    375:        Ri = lrand();
                    376:        Ro = lrand();
                    377:        sha = lrand();
                    378:        shb = lrand();
                    379:        As = 0;
                    380:        Ad = 0;
                    381:        AT = 0;
                    382:        Aslow = gaddr(cursm, curr.min);
                    383:        Ashigh = gaddr(cursm, sub(curr.max, Pt(1,1)));
                    384:        Adlow = gaddr(curdm, curpt);
                    385:        Adhigh = gaddr(curdm, sub(add(curpt, sub(curr.max,curr.min)),Pt(1,1)));
                    386: #endif
                    387: 
                    388: loop:
                    389: #ifdef TEST
                    390:        switch(*pc) {
                    391:        case load_Rs_P:
                    392:        case load_Rt_P:
                    393:        case load_Ru_P:
                    394:        case load_Rd:
                    395:        case load_Rs:
                    396:        case load_Rt:
                    397:                        if(As < Aslow || As > Ashigh){
                    398:                                print("load from bad As %ux\n", As);
                    399:                errplace:
                    400:                                print("src bitmap base %ux zero %d width %d r %d %d %d %d\n",
                    401:                                        cursm->base, cursm->zero, cursm->width,
                    402:                                        cursm->r.min.x, cursm->r.min.y,
                    403:                                        cursm->r.max.x, cursm->r.max.y);
                    404:                                print("dst bitmap base %ux zero %d width %d r %d %d %d %d\n",
                    405:                                        curdm->base, curdm->zero, curdm->width,
                    406:                                        curdm->r.min.x, curdm->r.min.y,
                    407:                                        curdm->r.max.x, curdm->r.max.y);
                    408:                                print("p %d %d r %d %d %d %d f %d\n",
                    409:                                        curpt.x, curpt.y, curr.min.x, curr.min.y,
                    410:                                        curr.max.x, curr.max.y, curf);
                    411:                                prprog();
                    412:                                exits("fail");
                    413:                        }
                    414:                        break;
                    415:        case load_Rd_D:
                    416:        case load_Rs_D:
                    417:        case load_Rt_D:
                    418:                        if(As-1 < Aslow || As-1 > Ashigh){
                    419:                                print("load from bad As-1 %ux\n", As-1);
                    420:                                goto errplace;
                    421:                        }
                    422:                        break;
                    423:        case fetch_Rd_P:
                    424:        case fetch_Rd:
                    425:                        if(Ad < Adlow || Ad > Adhigh){
                    426:                                print("fetch from bad Ad %ux\n", Ad);
                    427:                                goto errplace;
                    428:                        }
                    429:                        break;
                    430:        case store_Rs_P:
                    431:        case store_Rs:
                    432:                        if(Ad < Adlow || Ad > Adhigh){
                    433:                                print("store to bad Ad %ux\n", Ad);
                    434:                                goto errplace;
                    435:                        }
                    436:                        break;
                    437:        case fetch_Rd_D:
                    438:        case store_Rs_D:
                    439:                        if(Ad-1 < Adlow || Ad-1 > Adhigh){
                    440:                                print("fetch from bad Ad-1 %ux\n", Ad-1);
                    441:                                prprog();
                    442:                        }
                    443:                        break;
                    444:        }
                    445: #endif
                    446:        switch(*pc++) {
                    447:        default:
                    448: #ifdef TEST
                    449:                print("unknown opcode %d\n", pc[-1]);
                    450:                goto errplace;
                    451: #else
                    452:                return;
                    453: #endif
                    454:        case field:
                    455:                /* Rs gets Rd where mask bits are 0s, Rs where mask bits are 1s */
                    456:                Rs = ((Rs ^ Rd) & *pc++) ^ Rd;
                    457:                break;
                    458: 
                    459:        case lsha_RsRt:
                    460:                Rs = Rt << sha;
                    461:                break;
                    462: 
                    463:        case lshb_RsRt:
                    464:                Rs = Rt << shb;
                    465:                break;
                    466: 
                    467:        case lsh_RsRd:
                    468:                Rs = Rd << *pc++;
                    469:                break;
                    470: 
                    471:        case lsh_RtRt:  /* arg = shift amount */
                    472:                Rt <<= *pc++;
                    473:                break;
                    474: 
                    475:        case lsha_RtRt:
                    476:                Rt <<= sha;
                    477:                break;
                    478: 
                    479:        case lsha_RtRu:
                    480:                Rt = Ru << sha;
                    481:                break;
                    482: 
                    483:        case lshb_RtRu:
                    484:                Rt = Ru << shb;
                    485:                break;
                    486: 
                    487:        case rsha_RsRt:
                    488:                Rs = Rt >> sha;
                    489:                break;
                    490: 
                    491:        case rshb_RsRt:
                    492:                Rs = Rt >> shb;
                    493:                break;
                    494: 
                    495:        case rsha_RtRu:
                    496:                Rt = Ru >> sha;
                    497:                break;
                    498: 
                    499:        case rshb_RtRu:
                    500:                Rt = Ru >> shb;
                    501:                break;
                    502: 
                    503:        case orlsha_RsRt:
                    504:                Rs |= Rt << sha;
                    505:                break;
                    506: 
                    507:        case orlshb_RsRt:
                    508:                Rs |= Rt << shb;
                    509:                break;
                    510: 
                    511:        case orlsh_RsRd:        /* arg = shift amount */
                    512:                Rs |= Rd << *pc++;
                    513:                break;
                    514: 
                    515:        case orrsha_RsRt:
                    516:                Rs |= Rt >> sha;
                    517:                break;
                    518: 
                    519:        case orrshb_RsRt:
                    520:                Rs |= Rt >> shb;
                    521:                break;
                    522: 
                    523:        case orrsha_RtRu:
                    524:                Rt |= Ru >> sha;
                    525:                break;
                    526: 
                    527:        case orrshb_RtRu:
                    528:                Rt |= Ru >> shb;
                    529:                break;
                    530: 
                    531:        case or_RsRd:
                    532:                Rs |= Rd;
                    533:                break;
                    534: 
                    535:        case add_As:
                    536:                As = (ulong*)((char*)As + (long)*pc++);
                    537:                break;
                    538: 
                    539:        case add_Ad:
                    540:                Ad = (ulong*)((char*)Ad + (long)*pc++);
                    541:                break;
                    542: 
                    543:        case initsd:
                    544:                As = (ulong*)pc[0];
                    545:                Ad = (ulong*)pc[1];
                    546:                pc += 2;
                    547:                break;
                    548: 
                    549:        case ilabel:
                    550:                /* initialize inner loop count */
                    551:                Ri = *pc++;
                    552:                break;
                    553: 
                    554:        case olabel:
                    555:                /* initialize outer loop count */
                    556:                Ro = *pc++;
                    557:                break;
                    558: 
                    559:        case iloop:
                    560:                /* decrement inner loop count, loop back if still positive */
                    561:                Ri--;
                    562:                if(Ri > 0) {
                    563:                        pc = (Type*)pc[0];
                    564:                        break;
                    565:                }
                    566:                pc++;
                    567:                break;
                    568: 
                    569:        case oloop:
                    570:                /* decrement outer loop count, loop back if still positive */
                    571:                Ro--;
                    572:                if(Ro > 0) {
                    573:                        pc = (Type*)pc[0];
                    574:                        break;
                    575:                }
                    576:                pc++;
                    577:                break;
                    578: 
                    579:        case rts:
                    580:                return;
                    581: 
                    582:        case load_Rs_P:
                    583:                Rs = *As++;
                    584:                break;
                    585: 
                    586:        case load_Rt_P:
                    587:                Rt = *As++;
                    588:                break;
                    589: 
                    590:        case load_Ru_P:
                    591:                Ru = *As++;
                    592:                break;
                    593: 
                    594:        case load_Rd_D:
                    595:                Rd = *--As;
                    596:                break;
                    597: 
                    598:        case load_Rs_D:
                    599:                Rs = *--As;
                    600:                break;
                    601: 
                    602:        case load_Rt_D:
                    603:                Rt = *--As;
                    604:                break;
                    605: 
                    606:        case load_Rd:
                    607:                Rd = *As;
                    608:                break;
                    609: 
                    610:        case load_Rs:
                    611:                Rs = *As;
                    612:                break;
                    613: 
                    614:        case load_Rt:
                    615:                Rt = *As;
                    616:                break;
                    617: 
                    618:        case fetch_Rd_P:
                    619:                Rd = *Ad++;
                    620:                break;
                    621: 
                    622:        case fetch_Rd_D:
                    623:                Rd = *--Ad;
                    624:                break;
                    625: 
                    626:        case fetch_Rd:
                    627:                Rd = *Ad;
                    628:                break;
                    629: 
                    630:        case store_Rs_P:
                    631:                *Ad++ = Rs;
                    632:                break;
                    633: 
                    634:        case store_Rs_D:
                    635:                *--Ad = Rs;
                    636:                break;
                    637: 
                    638:        case store_Rs:
                    639:                *Ad = Rs;
                    640:                break;
                    641: 
                    642:        case inittab:
                    643:                AT = (uchar*)pc[0];
                    644:                osiz = (long)pc[1];
                    645:                pc += 2;
                    646:                break;
                    647: 
                    648:        case initsh:
                    649:                sha = (long)pc[0];
                    650:                shb = (long)pc[1];
                    651:                pc += 2;
                    652:                break;
                    653: 
                    654:        case table_RdRt:
                    655:                /*
                    656:                 * Starting at offset arg1 in Rt, take arg2 bits,
                    657:                 * and use it to look up in table AT, putting answer in Rd
                    658:                 */
                    659:                tmp = (long)pc[1];
                    660:                Rd = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
                    661:                switch(osiz){
                    662:                case 1:
                    663:                        Rd = AT[Rd];
                    664:                        break;
                    665:                case 2:
                    666:                        Rd = ((ushort*)AT)[Rd];
                    667:                        break;
                    668:                case 4:
                    669:                        Rd = ((ulong*)AT)[Rd];
                    670:                        break;
                    671:                }
                    672:                pc += 2;
                    673:                break;
                    674: 
                    675:        case table_RsRt:
                    676:                /* like table_RdRt, but answer goes in Rs */
                    677:                tmp = (long)pc[1];
                    678:                Rs = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
                    679:                switch(osiz){
                    680:                case 1:
                    681:                        Rs = AT[Rs];
                    682:                        break;
                    683:                case 2:
                    684:                        Rs = ((ushort*)AT)[Rs];
                    685:                        break;
                    686:                case 4:
                    687:                        Rs = ((ulong*)AT)[Rs];
                    688:                        break;
                    689:                }
                    690:                pc += 2;
                    691:                break;
                    692: 
                    693: 
                    694:        case assemble:
                    695:                /*
                    696:                 * Move low arg2 bits of Rd into offset arg1 in Rs.
                    697:                 * Can assume that high bits of Rd are zero,
                    698:                 * and target field of Rs is zero if offset != 0
                    699:                 */
                    700:                tmp = (long)pc[0];
                    701:                if(tmp == 0)
                    702:                        Rs = Rd << (32-pc[1]);
                    703:                else
                    704:                        Rs |= Rd << (32-(tmp+pc[1]));
                    705:                pc += 2;
                    706:                break;
                    707:                
                    708:        case assemblex:
                    709:                /*
                    710:                 * Like assemble, but fields will be moved into
                    711:                 * proper position by later Assemblex's
                    712:                 */
                    713:                tmp = (long)pc[0];
                    714:                if(tmp == 0)
                    715:                        Rs = Rd;
                    716:                else
                    717:                        Rs = (Rs << pc[1]) | Rd;
                    718:                pc += 2;
                    719:                break;
                    720:                
                    721:        case Ozero:
                    722:                Rs = 0;
                    723:                break;
                    724: 
                    725:        case ODnorS:
                    726:                Rs = ~(Rd|Rs);
                    727:                break;
                    728: 
                    729:        case ODandnotS:
                    730:                Rs = Rd & ~Rs;
                    731:                break;
                    732: 
                    733:        case OnotS:
                    734:                Rs = ~Rs;
                    735:                break;
                    736: 
                    737:        case OnotDandS:
                    738:                Rs = ~Rd & Rs;
                    739:                break;
                    740: 
                    741:        case OnotD:
                    742:                Rs = ~Rd;
                    743:                break;
                    744: 
                    745:        case ODxorS:
                    746:                Rs ^= Rd;
                    747:                break;
                    748: 
                    749:        case ODnandS:
                    750:                Rs = ~(Rd & Rs);
                    751:                break;
                    752: 
                    753:        case ODandS:
                    754:                Rs &= Rd;
                    755:                break;
                    756: 
                    757:        case ODxnorS:
                    758:                Rs = ~(Rd ^ Rs);
                    759:                break;
                    760: 
                    761:        case OD:
                    762:                Rs = Rd;
                    763:                break;
                    764: 
                    765:        case ODornotS:
                    766:                Rs = Rd | ~Rs;
                    767:                break;
                    768: 
                    769:        case OnotDorS:
                    770:                Rs |= ~Rd;
                    771:                break;
                    772: 
                    773:        case ODorS:
                    774:                Rs |= Rd;
                    775:                break;
                    776: 
                    777:        case OF:
                    778:                Rs = ~0L;
                    779:                break;
                    780:        }
                    781:        goto loop;
                    782: }
                    783: 
                    784: #ifdef TEST
                    785: void
                    786: prprog(void)
                    787: {
                    788:        Type *pc;
                    789:        int osiz;
                    790: 
                    791:        pc = (Type *)mem;
                    792: 
                    793: loop:
                    794:        switch(*pc++) {
                    795:        default:
                    796:                print("unknown opcode %d\n", pc[-1]);
                    797:                exits("unknown opcode");
                    798:        case field:
                    799:                print("Rs = ((Rs ^ Rd) & 0x%lux) ^ Rd\n", *pc++);
                    800:                break;
                    801: 
                    802:        case lsha_RsRt:
                    803:                print("Rs = Rt << sha\n");
                    804:                break;
                    805: 
                    806:        case lshb_RsRt:
                    807:                print("Rs = Rt << shb\n");
                    808:                break;
                    809: 
                    810:        case lsh_RsRd:
                    811:                print("Rs = Rd << %d\n", *pc++);
                    812:                break;
                    813: 
                    814:        case lsh_RtRt:
                    815:                print("Rt <<= %d\n", *pc++);
                    816:                break;
                    817: 
                    818:        case lsha_RtRt:
                    819:                print("Rt <<= sha\n");
                    820:                break;
                    821: 
                    822:        case lsha_RtRu:
                    823:                print("Rt = Ru << sha\n");
                    824:                break;
                    825: 
                    826:        case lshb_RtRu:
                    827:                print("Rt = Ru << shb\n");
                    828:                break;
                    829: 
                    830:        case rsha_RsRt:
                    831:                print("Rs = Rt >> sha\n");
                    832:                break;
                    833: 
                    834:        case rshb_RsRt:
                    835:                print("Rs = Rt >> shb\n");
                    836:                break;
                    837: 
                    838:        case rsha_RtRu:
                    839:                print("Rt = Ru >> sha\n");
                    840:                break;
                    841: 
                    842:        case rshb_RtRu:
                    843:                print("Rt = Ru >> shb\n");
                    844:                break;
                    845: 
                    846:        case orlsha_RsRt:
                    847:                print("Rs |= Rt << sha\n");
                    848:                break;
                    849: 
                    850:        case orlshb_RsRt:
                    851:                print("Rs |= Rt << shb\n");
                    852:                break;
                    853: 
                    854:        case orlsh_RsRd:
                    855:                print("Rs |= Rd << %d\n", *pc++);
                    856:                break;
                    857: 
                    858:        case orrsha_RsRt:
                    859:                print("Rs |= Rt >> sha\n");
                    860:                break;
                    861: 
                    862:        case orrshb_RsRt:
                    863:                print("Rs |= Rt >> shb\n");
                    864:                break;
                    865: 
                    866:        case orrsha_RtRu:
                    867:                print("Rt |= Ru >> sha\n");
                    868:                break;
                    869: 
                    870:        case orrshb_RtRu:
                    871:                print("Rt |= Ru >> shb\n");
                    872:                break;
                    873: 
                    874:        case or_RsRd:
                    875:                print("Rs |= Rd\n");
                    876:                break;
                    877: 
                    878:        case add_As:
                    879:                print("As += %d\n", (long)*pc++);
                    880:                break;
                    881: 
                    882:        case add_Ad:
                    883:                print("Ad += %d\n", (long)*pc++);
                    884:                break;
                    885: 
                    886:        case initsd:
                    887:                print("As = 0x%lux\n", (ulong*)pc[0]);
                    888:                print("Ad = 0x%lux\n", (ulong*)pc[1]);
                    889:                pc += 2;
                    890:                break;
                    891: 
                    892:        case ilabel:
                    893:                print("Ri = %d\n", *pc++);
                    894:                break;
                    895: 
                    896:        case olabel:
                    897:                print("Ro = %d\n", *pc++);
                    898:                break;
                    899: 
                    900:        case iloop:
                    901:                print("if(--Ri > 0) goto 0x%lux\n", *pc++);
                    902:                break;
                    903: 
                    904:        case oloop:
                    905:                print("if(--Ro > 0) goto 0x%lux\n", *pc++);
                    906:                break;
                    907: 
                    908:        case rts:
                    909:                print("return\n");
                    910:                return;
                    911: 
                    912:        case load_Rs_P:
                    913:                print("Rs = *As++\n");
                    914:                break;
                    915: 
                    916:        case load_Rt_P:
                    917:                print("Rt = *As++\n");
                    918:                break;
                    919: 
                    920:        case load_Ru_P:
                    921:                print("Ru = *As++\n");
                    922:                break;
                    923: 
                    924:        case load_Rd_D:
                    925:                print("Rd = *--As\n");
                    926:                break;
                    927: 
                    928:        case load_Rs_D:
                    929:                print("Rs = *--As\n");
                    930:                break;
                    931: 
                    932:        case load_Rt_D:
                    933:                print("Rt = *--As\n");
                    934:                break;
                    935: 
                    936:        case load_Rd:
                    937:                print("Rd = *As\n");
                    938:                break;
                    939: 
                    940:        case load_Rs:
                    941:                print("Rs = *As\n");
                    942:                break;
                    943: 
                    944:        case load_Rt:
                    945:                print("Rt = *As\n");
                    946:                break;
                    947: 
                    948:        case fetch_Rd_P:
                    949:                print("Rd = *Ad++\n");
                    950:                break;
                    951: 
                    952:        case fetch_Rd_D:
                    953:                print("Rd = *--Ad\n");
                    954:                break;
                    955: 
                    956:        case fetch_Rd:
                    957:                print("Rd = *Ad\n");
                    958:                break;
                    959: 
                    960:        case store_Rs_P:
                    961:                print("*Ad++ = Rs\n");
                    962:                break;
                    963: 
                    964:        case store_Rs_D:
                    965:                print("*--Ad = Rs\n");
                    966:                break;
                    967: 
                    968:        case store_Rs:
                    969:                print("*Ad = Rs\n");
                    970:                break;
                    971: 
                    972:        case inittab:
                    973:                print("AT = 0x%lux (%d byte entries)\n", pc[0],pc[1]);
                    974:                osiz = pc[1];
                    975:                pc += 2;
                    976:                break;
                    977: 
                    978:        case initsh:
                    979:                print("sha = %d\n", (long)pc[0]);
                    980:                print("shb = %d\n", (long)pc[1]);
                    981:                pc += 2;
                    982:                break;
                    983: 
                    984:        case table_RdRt:
                    985:                switch(osiz){
                    986:                case 1:
                    987:                        print("Rd = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                    988:                        break;
                    989:                case 2:
                    990:                        print("Rd = ((short*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                    991:                        break;
                    992:                case 4:
                    993:                        print("Rd = ((long*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                    994:                        break;
                    995:                default:
                    996:                        print("bad osiz for table_RdRt\n");
                    997:                }
                    998:                pc += 2;
                    999:                break;
                   1000: 
                   1001:        case table_RsRt:
                   1002:                switch(osiz){
                   1003:                case 1:
                   1004:                        print("Rs = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1005:                        break;
                   1006:                case 2:
                   1007:                        print("Rs = ((short*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1008:                        break;
                   1009:                case 4:
                   1010:                        print("Rs = ((long*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1011:                        break;
                   1012:                default:
                   1013:                        print("bad osiz for table_RdRt\n");
                   1014:                }
                   1015:                pc += 2;
                   1016:                break;
                   1017: 
                   1018:        case assemble:
                   1019:                /*
                   1020:                 * Move low arg2 bits of Rd into offset arg1 in Rs.
                   1021:                 * Can assume that high bits of Rd are zero,
                   1022:                 * and target field of Rs is zero if offset != 0
                   1023:                 */
                   1024:                if(pc[0] == 0)
                   1025:                        print("Rs = Rd << %d\n", (32-(long)pc[1]));
                   1026:                else
                   1027:                        print("Rs |= Rd << %d\n", (32-((long)pc[0]+(long)pc[1])));
                   1028:                pc += 2;
                   1029:                break;
                   1030:                
                   1031:        case assemblex:
                   1032:                /*
                   1033:                 * Like assemble, but fields will be moved into
                   1034:                 * proper position by later Assemblex's
                   1035:                 */
                   1036:                if(pc[0] == 0)
                   1037:                        print("Rs = Rd\n");
                   1038:                else
                   1039:                        print("Rs = (Rs << %d) | Rd\n", pc[1]);
                   1040:                pc += 2;
                   1041:                break;
                   1042:                
                   1043:        case Ozero:
                   1044:                print("Rs = 0\n");
                   1045:                break;
                   1046: 
                   1047:        case ODnorS:
                   1048:                print("Rs = ~(Rd|Rs)\n");
                   1049:                break;
                   1050: 
                   1051:        case ODandnotS:
                   1052:                print("Rs = Rd & ~Rs\n");
                   1053:                break;
                   1054: 
                   1055:        case OnotS:
                   1056:                print("Rs = ~Rs\n");
                   1057:                break;
                   1058: 
                   1059:        case OnotDandS:
                   1060:                print("Rs = ~Rd & Rs\n");
                   1061:                break;
                   1062: 
                   1063:        case OnotD:
                   1064:                print("Rs = ~Rd\n");
                   1065:                break;
                   1066: 
                   1067:        case ODxorS:
                   1068:                print("Rs ^= Rd\n");
                   1069:                break;
                   1070: 
                   1071:        case ODnandS:
                   1072:                print("Rs = ~(Rd & Rs)\n");
                   1073:                break;
                   1074: 
                   1075:        case ODandS:
                   1076:                print("Rs &= Rd\n");
                   1077:                break;
                   1078: 
                   1079:        case ODxnorS:
                   1080:                print("Rs = ~(Rd ^ Rs)\n");
                   1081:                break;
                   1082: 
                   1083:        case OD:
                   1084:                print("Rs = Rd\n");
                   1085:                break;
                   1086: 
                   1087:        case ODornotS:
                   1088:                print("Rs = Rd | ~Rs\n");
                   1089:                break;
                   1090: 
                   1091:        case OnotDorS:
                   1092:                print("Rs |= ~Rd\n");
                   1093:                break;
                   1094: 
                   1095:        case ODorS:
                   1096:                print("Rs |= Rd\n");
                   1097:                break;
                   1098: 
                   1099:        case OF:
                   1100:                print("Rs = ~0L\n");
                   1101:                break;
                   1102:        }
                   1103:        goto loop;
                   1104: }
                   1105: #endif
                   1106: 

unix.superglobalmegacorp.com

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