Annotation of lucent/sys/src/libgnot/bbc.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: static uchar *tabs[4][4] =
                    353: {
                    354:        {            0, (uchar*)tab01, (uchar*)tab02, (uchar*)tab03},
                    355:        {(uchar*)tab10,             0, (uchar*)tab12, (uchar*)tab13},
                    356:        {(uchar*)tab20, (uchar*)tab21,             0, (uchar*)tab23},
                    357:        {(uchar*)tab30, (uchar*)tab31, (uchar*)tab32,             0},
                    358: };
                    359: 
                    360: static uchar tabosiz[4][4] = /* size in bytes of entries */
                    361: {
                    362:        { 0, 2, 4, 4},
                    363:        { 1, 0, 2, 4},
                    364:        { 1, 1, 0, 2},
                    365:        { 1, 1, 1, 0},
                    366: };
                    367: 
                    368: enum {
                    369:        Progmax = 800,          /* max number of words in a bitblt prog */
                    370:        Progmaxnoconv = 50,     /* max number of words when no conversion */
                    371: };
                    372: 
                    373: static void
                    374: interpret(Type *pc)
                    375: {
                    376:        ulong *As, *Ad;
                    377:        ulong Rs, Rd, Rt, Ru;
                    378:        long Ri, Ro;
                    379:        uchar *AT;
                    380:        int osiz, sha, shb, tmp;
                    381: 
                    382: #ifdef TEST
                    383:        ulong *Aslow, *Ashigh, *Adlow, *Adhigh;
                    384:        void prprog(void);
                    385: 
                    386:        Rs = lrand();
                    387:        Rd = lrand();
                    388:        Rt = lrand();
                    389:        Ru = lrand();
                    390:        Ri = lrand();
                    391:        Ro = lrand();
                    392:        sha = lrand();
                    393:        shb = lrand();
                    394:        As = 0;
                    395:        Ad = 0;
                    396:        AT = 0;
                    397:        Aslow = gaddr(cursm, curr.min);
                    398:        Ashigh = gaddr(cursm, sub(curr.max, Pt(1,1)));
                    399:        Adlow = gaddr(curdm, curpt);
                    400:        Adhigh = gaddr(curdm, sub(add(curpt, sub(curr.max,curr.min)),Pt(1,1)));
                    401: #endif
                    402: 
                    403: loop:
                    404: #ifdef TEST
                    405:        switch(*pc) {
                    406:        case load_Rs_P:
                    407:        case load_Rt_P:
                    408:        case load_Ru_P:
                    409:        case load_Rd:
                    410:        case load_Rs:
                    411:        case load_Rt:
                    412:                        if(As < Aslow || As > Ashigh){
                    413:                                print("load from bad As %ux\n", As);
                    414:                errplace:
                    415:                                print("src bitmap base %ux zero %d width %d r %d %d %d %d\n",
                    416:                                        cursm->base, cursm->zero, cursm->width,
                    417:                                        cursm->r.min.x, cursm->r.min.y,
                    418:                                        cursm->r.max.x, cursm->r.max.y);
                    419:                                print("dst bitmap base %ux zero %d width %d r %d %d %d %d\n",
                    420:                                        curdm->base, curdm->zero, curdm->width,
                    421:                                        curdm->r.min.x, curdm->r.min.y,
                    422:                                        curdm->r.max.x, curdm->r.max.y);
                    423:                                print("p %d %d r %d %d %d %d f %d\n",
                    424:                                        curpt.x, curpt.y, curr.min.x, curr.min.y,
                    425:                                        curr.max.x, curr.max.y, curf);
                    426:                                prprog();
                    427:                                exits("fail");
                    428:                        }
                    429:                        break;
                    430:        case load_Rd_D:
                    431:        case load_Rs_D:
                    432:        case load_Rt_D:
                    433:                        if(As-1 < Aslow || As-1 > Ashigh){
                    434:                                print("load from bad As-1 %ux\n", As-1);
                    435:                                goto errplace;
                    436:                        }
                    437:                        break;
                    438:        case fetch_Rd_P:
                    439:        case fetch_Rd:
                    440:                        if(Ad < Adlow || Ad > Adhigh){
                    441:                                print("fetch from bad Ad %ux\n", Ad);
                    442:                                goto errplace;
                    443:                        }
                    444:                        break;
                    445:        case store_Rs_P:
                    446:        case store_Rs:
                    447:                        if(Ad < Adlow || Ad > Adhigh){
                    448:                                print("store to bad Ad %ux\n", Ad);
                    449:                                goto errplace;
                    450:                        }
                    451:                        break;
                    452:        case fetch_Rd_D:
                    453:        case store_Rs_D:
                    454:                        if(Ad-1 < Adlow || Ad-1 > Adhigh){
                    455:                                print("fetch from bad Ad-1 %ux\n", Ad-1);
                    456:                                prprog();
                    457:                        }
                    458:                        break;
                    459:        }
                    460: #endif
                    461:        switch(*pc++) {
                    462:        default:
                    463: #ifdef TEST
                    464:                print("unknown opcode %d\n", pc[-1]);
                    465:                goto errplace;
                    466: #else
                    467:                return;
                    468: #endif
                    469:        case field:
                    470:                /* Rs gets Rd where mask bits are 0s, Rs where mask bits are 1s */
                    471:                Rs = ((Rs ^ Rd) & *pc++) ^ Rd;
                    472:                break;
                    473: 
                    474:        case lsha_RsRt:
                    475:                Rs = Rt << sha;
                    476:                break;
                    477: 
                    478:        case lshb_RsRt:
                    479:                Rs = Rt << shb;
                    480:                break;
                    481: 
                    482:        case lsh_RsRd:
                    483:                Rs = Rd << *pc++;
                    484:                break;
                    485: 
                    486:        case lsh_RtRt:  /* arg = shift amount */
                    487:                Rt <<= *pc++;
                    488:                break;
                    489: 
                    490:        case lsha_RtRt:
                    491:                Rt <<= sha;
                    492:                break;
                    493: 
                    494:        case lsha_RtRu:
                    495:                Rt = Ru << sha;
                    496:                break;
                    497: 
                    498:        case lshb_RtRu:
                    499:                Rt = Ru << shb;
                    500:                break;
                    501: 
                    502:        case rsha_RsRt:
                    503:                Rs = Rt >> sha;
                    504:                break;
                    505: 
                    506:        case rshb_RsRt:
                    507:                Rs = Rt >> shb;
                    508:                break;
                    509: 
                    510:        case rsha_RtRu:
                    511:                Rt = Ru >> sha;
                    512:                break;
                    513: 
                    514:        case rshb_RtRu:
                    515:                Rt = Ru >> shb;
                    516:                break;
                    517: 
                    518:        case orlsha_RsRt:
                    519:                Rs |= Rt << sha;
                    520:                break;
                    521: 
                    522:        case orlshb_RsRt:
                    523:                Rs |= Rt << shb;
                    524:                break;
                    525: 
                    526:        case orlsh_RsRd:        /* arg = shift amount */
                    527:                Rs |= Rd << *pc++;
                    528:                break;
                    529: 
                    530:        case orrsha_RsRt:
                    531:                Rs |= Rt >> sha;
                    532:                break;
                    533: 
                    534:        case orrshb_RsRt:
                    535:                Rs |= Rt >> shb;
                    536:                break;
                    537: 
                    538:        case orrsha_RtRu:
                    539:                Rt |= Ru >> sha;
                    540:                break;
                    541: 
                    542:        case orrshb_RtRu:
                    543:                Rt |= Ru >> shb;
                    544:                break;
                    545: 
                    546:        case or_RsRd:
                    547:                Rs |= Rd;
                    548:                break;
                    549: 
                    550:        case add_As:
                    551:                As = (ulong*)((char*)As + (long)*pc++);
                    552:                break;
                    553: 
                    554:        case add_Ad:
                    555:                Ad = (ulong*)((char*)Ad + (long)*pc++);
                    556:                break;
                    557: 
                    558:        case initsd:
                    559:                As = (ulong*)pc[0];
                    560:                Ad = (ulong*)pc[1];
                    561:                pc += 2;
                    562:                break;
                    563: 
                    564:        case ilabel:
                    565:                /* initialize inner loop count */
                    566:                Ri = *pc++;
                    567:                break;
                    568: 
                    569:        case olabel:
                    570:                /* initialize outer loop count */
                    571:                Ro = *pc++;
                    572:                break;
                    573: 
                    574:        case iloop:
                    575:                /* decrement inner loop count, loop back if still positive */
                    576:                Ri--;
                    577:                if(Ri > 0) {
                    578:                        pc = (Type*)pc[0];
                    579:                        break;
                    580:                }
                    581:                pc++;
                    582:                break;
                    583: 
                    584:        case oloop:
                    585:                /* decrement outer loop count, loop back if still positive */
                    586:                Ro--;
                    587:                if(Ro > 0) {
                    588:                        pc = (Type*)pc[0];
                    589:                        break;
                    590:                }
                    591:                pc++;
                    592:                break;
                    593: 
                    594:        case rts:
                    595:                return;
                    596: 
                    597:        case load_Rs_P:
                    598:                Rs = *As++;
                    599:                break;
                    600: 
                    601:        case load_Rt_P:
                    602:                Rt = *As++;
                    603:                break;
                    604: 
                    605:        case load_Ru_P:
                    606:                Ru = *As++;
                    607:                break;
                    608: 
                    609:        case load_Rd_D:
                    610:                Rd = *--As;
                    611:                break;
                    612: 
                    613:        case load_Rs_D:
                    614:                Rs = *--As;
                    615:                break;
                    616: 
                    617:        case load_Rt_D:
                    618:                Rt = *--As;
                    619:                break;
                    620: 
                    621:        case load_Rd:
                    622:                Rd = *As;
                    623:                break;
                    624: 
                    625:        case load_Rs:
                    626:                Rs = *As;
                    627:                break;
                    628: 
                    629:        case load_Rt:
                    630:                Rt = *As;
                    631:                break;
                    632: 
                    633:        case fetch_Rd_P:
                    634:                Rd = *Ad++;
                    635:                break;
                    636: 
                    637:        case fetch_Rd_D:
                    638:                Rd = *--Ad;
                    639:                break;
                    640: 
                    641:        case fetch_Rd:
                    642:                Rd = *Ad;
                    643:                break;
                    644: 
                    645:        case store_Rs_P:
                    646:                *Ad++ = Rs;
                    647:                break;
                    648: 
                    649:        case store_Rs_D:
                    650:                *--Ad = Rs;
                    651:                break;
                    652: 
                    653:        case store_Rs:
                    654:                *Ad = Rs;
                    655:                break;
                    656: 
                    657:        case inittab:
                    658:                AT = (uchar*)pc[0];
                    659:                osiz = (long)pc[1];
                    660:                pc += 2;
                    661:                break;
                    662: 
                    663:        case initsh:
                    664:                sha = (long)pc[0];
                    665:                shb = (long)pc[1];
                    666:                pc += 2;
                    667:                break;
                    668: 
                    669:        case table_RdRt:
                    670:                /*
                    671:                 * Starting at offset arg1 in Rt, take arg2 bits,
                    672:                 * and use it to look up in table AT, putting answer in Rd
                    673:                 */
                    674:                tmp = (long)pc[1];
                    675:                Rd = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
                    676:                switch(osiz){
                    677:                case 1:
                    678:                        Rd = AT[Rd];
                    679:                        break;
                    680:                case 2:
                    681:                        Rd = ((ushort*)AT)[Rd];
                    682:                        break;
                    683:                case 4:
                    684:                        Rd = ((ulong*)AT)[Rd];
                    685:                        break;
                    686:                }
                    687:                pc += 2;
                    688:                break;
                    689: 
                    690:        case table_RsRt:
                    691:                /* like table_RdRt, but answer goes in Rs */
                    692:                tmp = (long)pc[1];
                    693:                Rs = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
                    694:                switch(osiz){
                    695:                case 1:
                    696:                        Rs = AT[Rs];
                    697:                        break;
                    698:                case 2:
                    699:                        Rs = ((ushort*)AT)[Rs];
                    700:                        break;
                    701:                case 4:
                    702:                        Rs = ((ulong*)AT)[Rs];
                    703:                        break;
                    704:                }
                    705:                pc += 2;
                    706:                break;
                    707: 
                    708: 
                    709:        case assemble:
                    710:                /*
                    711:                 * Move low arg2 bits of Rd into offset arg1 in Rs.
                    712:                 * Can assume that high bits of Rd are zero,
                    713:                 * and target field of Rs is zero if offset != 0
                    714:                 */
                    715:                tmp = (long)pc[0];
                    716:                if(tmp == 0)
                    717:                        Rs = Rd << (32-pc[1]);
                    718:                else
                    719:                        Rs |= Rd << (32-(tmp+pc[1]));
                    720:                pc += 2;
                    721:                break;
                    722:                
                    723:        case assemblex:
                    724:                /*
                    725:                 * Like assemble, but fields will be moved into
                    726:                 * proper position by later Assemblex's
                    727:                 */
                    728:                tmp = (long)pc[0];
                    729:                if(tmp == 0)
                    730:                        Rs = Rd;
                    731:                else
                    732:                        Rs = (Rs << pc[1]) | Rd;
                    733:                pc += 2;
                    734:                break;
                    735:                
                    736:        case Ozero:
                    737:                Rs = 0;
                    738:                break;
                    739: 
                    740:        case ODnorS:
                    741:                Rs = ~(Rd|Rs);
                    742:                break;
                    743: 
                    744:        case ODandnotS:
                    745:                Rs = Rd & ~Rs;
                    746:                break;
                    747: 
                    748:        case OnotS:
                    749:                Rs = ~Rs;
                    750:                break;
                    751: 
                    752:        case OnotDandS:
                    753:                Rs = ~Rd & Rs;
                    754:                break;
                    755: 
                    756:        case OnotD:
                    757:                Rs = ~Rd;
                    758:                break;
                    759: 
                    760:        case ODxorS:
                    761:                Rs ^= Rd;
                    762:                break;
                    763: 
                    764:        case ODnandS:
                    765:                Rs = ~(Rd & Rs);
                    766:                break;
                    767: 
                    768:        case ODandS:
                    769:                Rs &= Rd;
                    770:                break;
                    771: 
                    772:        case ODxnorS:
                    773:                Rs = ~(Rd ^ Rs);
                    774:                break;
                    775: 
                    776:        case OD:
                    777:                Rs = Rd;
                    778:                break;
                    779: 
                    780:        case ODornotS:
                    781:                Rs = Rd | ~Rs;
                    782:                break;
                    783: 
                    784:        case OnotDorS:
                    785:                Rs |= ~Rd;
                    786:                break;
                    787: 
                    788:        case ODorS:
                    789:                Rs |= Rd;
                    790:                break;
                    791: 
                    792:        case OF:
                    793:                Rs = ~0L;
                    794:                break;
                    795:        }
                    796:        goto loop;
                    797: }
                    798: 
                    799: #ifdef TEST
                    800: void
                    801: prprog(void)
                    802: {
                    803:        int osiz;
                    804:        Type *pc;
                    805:        pc = (Type *)mem;
                    806: 
                    807: loop:
                    808:        switch(*pc++) {
                    809:        default:
                    810:                print("unknown opcode %d\n", pc[-1]);
                    811:                exits("unknown opcode");
                    812:        case field:
                    813:                print("Rs = ((Rs ^ Rd) & 0x%lux) ^ Rd\n", *pc++);
                    814:                break;
                    815: 
                    816:        case lsha_RsRt:
                    817:                print("Rs = Rt << sha\n");
                    818:                break;
                    819: 
                    820:        case lshb_RsRt:
                    821:                print("Rs = Rt << shb\n");
                    822:                break;
                    823: 
                    824:        case lsh_RsRd:
                    825:                print("Rs = Rd << %d\n", *pc++);
                    826:                break;
                    827: 
                    828:        case lsh_RtRt:
                    829:                print("Rt <<= %d\n", *pc++);
                    830:                break;
                    831: 
                    832:        case lsha_RtRt:
                    833:                print("Rt <<= sha\n");
                    834:                break;
                    835: 
                    836:        case lsha_RtRu:
                    837:                print("Rt = Ru << sha\n");
                    838:                break;
                    839: 
                    840:        case lshb_RtRu:
                    841:                print("Rt = Ru << shb\n");
                    842:                break;
                    843: 
                    844:        case rsha_RsRt:
                    845:                print("Rs = Rt >> sha\n");
                    846:                break;
                    847: 
                    848:        case rshb_RsRt:
                    849:                print("Rs = Rt >> shb\n");
                    850:                break;
                    851: 
                    852:        case rsha_RtRu:
                    853:                print("Rt = Ru >> sha\n");
                    854:                break;
                    855: 
                    856:        case rshb_RtRu:
                    857:                print("Rt = Ru >> shb\n");
                    858:                break;
                    859: 
                    860:        case orlsha_RsRt:
                    861:                print("Rs |= Rt << sha\n");
                    862:                break;
                    863: 
                    864:        case orlshb_RsRt:
                    865:                print("Rs |= Rt << shb\n");
                    866:                break;
                    867: 
                    868:        case orlsh_RsRd:
                    869:                print("Rs |= Rd << %d\n", *pc++);
                    870:                break;
                    871: 
                    872:        case orrsha_RsRt:
                    873:                print("Rs |= Rt >> sha\n");
                    874:                break;
                    875: 
                    876:        case orrshb_RsRt:
                    877:                print("Rs |= Rt >> shb\n");
                    878:                break;
                    879: 
                    880:        case orrsha_RtRu:
                    881:                print("Rt |= Ru >> sha\n");
                    882:                break;
                    883: 
                    884:        case orrshb_RtRu:
                    885:                print("Rt |= Ru >> shb\n");
                    886:                break;
                    887: 
                    888:        case or_RsRd:
                    889:                print("Rs |= Rd\n");
                    890:                break;
                    891: 
                    892:        case add_As:
                    893:                print("As += %d\n", (long)*pc++);
                    894:                break;
                    895: 
                    896:        case add_Ad:
                    897:                print("Ad += %d\n", (long)*pc++);
                    898:                break;
                    899: 
                    900:        case initsd:
                    901:                print("As = 0x%lux\n", (ulong*)pc[0]);
                    902:                print("Ad = 0x%lux\n", (ulong*)pc[1]);
                    903:                pc += 2;
                    904:                break;
                    905: 
                    906:        case ilabel:
                    907:                print("Ri = %d\n", *pc++);
                    908:                break;
                    909: 
                    910:        case olabel:
                    911:                print("Ro = %d\n", *pc++);
                    912:                break;
                    913: 
                    914:        case iloop:
                    915:                print("if(--Ri > 0) goto 0x%lux\n", *pc++);
                    916:                break;
                    917: 
                    918:        case oloop:
                    919:                print("if(--Ro > 0) goto 0x%lux\n", *pc++);
                    920:                break;
                    921: 
                    922:        case rts:
                    923:                print("return\n");
                    924:                return;
                    925: 
                    926:        case load_Rs_P:
                    927:                print("Rs = *As++\n");
                    928:                break;
                    929: 
                    930:        case load_Rt_P:
                    931:                print("Rt = *As++\n");
                    932:                break;
                    933: 
                    934:        case load_Ru_P:
                    935:                print("Ru = *As++\n");
                    936:                break;
                    937: 
                    938:        case load_Rd_D:
                    939:                print("Rd = *--As\n");
                    940:                break;
                    941: 
                    942:        case load_Rs_D:
                    943:                print("Rs = *--As\n");
                    944:                break;
                    945: 
                    946:        case load_Rt_D:
                    947:                print("Rt = *--As\n");
                    948:                break;
                    949: 
                    950:        case load_Rd:
                    951:                print("Rd = *As\n");
                    952:                break;
                    953: 
                    954:        case load_Rs:
                    955:                print("Rs = *As\n");
                    956:                break;
                    957: 
                    958:        case load_Rt:
                    959:                print("Rt = *As\n");
                    960:                break;
                    961: 
                    962:        case fetch_Rd_P:
                    963:                print("Rd = *Ad++\n");
                    964:                break;
                    965: 
                    966:        case fetch_Rd_D:
                    967:                print("Rd = *--Ad\n");
                    968:                break;
                    969: 
                    970:        case fetch_Rd:
                    971:                print("Rd = *Ad\n");
                    972:                break;
                    973: 
                    974:        case store_Rs_P:
                    975:                print("*Ad++ = Rs\n");
                    976:                break;
                    977: 
                    978:        case store_Rs_D:
                    979:                print("*--Ad = Rs\n");
                    980:                break;
                    981: 
                    982:        case store_Rs:
                    983:                print("*Ad = Rs\n");
                    984:                break;
                    985: 
                    986:        case inittab:
                    987:                print("AT = 0x%lux (%d byte entries)\n", pc[0],pc[1]);
                    988:                osiz = pc[1];
                    989:                pc += 2;
                    990:                break;
                    991: 
                    992:        case initsh:
                    993:                print("sha = %d\n", (long)pc[0]);
                    994:                print("shb = %d\n", (long)pc[1]);
                    995:                pc += 2;
                    996:                break;
                    997: 
                    998:        case table_RdRt:
                    999:                switch(osiz){
                   1000:                case 1:
                   1001:                        print("Rd = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1002:                        break;
                   1003:                case 2:
                   1004:                        print("Rd = ((short*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1005:                        break;
                   1006:                case 4:
                   1007:                        print("Rd = ((long*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1008:                        break;
                   1009:                default:
                   1010:                        print("bad osiz for table_RdRt\n");
                   1011:                }
                   1012:                pc += 2;
                   1013:                break;
                   1014: 
                   1015:        case table_RsRt:
                   1016:                switch(osiz){
                   1017:                case 1:
                   1018:                        print("Rs = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1019:                        break;
                   1020:                case 2:
                   1021:                        print("Rs = ((short*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1022:                        break;
                   1023:                case 4:
                   1024:                        print("Rs = ((long*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
                   1025:                        break;
                   1026:                default:
                   1027:                        print("bad osiz for table_RdRt\n");
                   1028:                }
                   1029:                pc += 2;
                   1030:                break;
                   1031: 
                   1032:        case assemble:
                   1033:                /*
                   1034:                 * Move low arg2 bits of Rd into offset arg1 in Rs.
                   1035:                 * Can assume that high bits of Rd are zero,
                   1036:                 * and target field of Rs is zero if offset != 0
                   1037:                 */
                   1038:                if(pc[0] == 0)
                   1039:                        print("Rs = Rd << %d\n", (32-(long)pc[1]));
                   1040:                else
                   1041:                        print("Rs |= Rd << %d\n", (32-((long)pc[0]+(long)pc[1])));
                   1042:                pc += 2;
                   1043:                break;
                   1044:                
                   1045:        case assemblex:
                   1046:                /*
                   1047:                 * Like assemble, but fields will be moved into
                   1048:                 * proper position by later Assemblex's
                   1049:                 */
                   1050:                if(pc[0] == 0)
                   1051:                        print("Rs = Rd\n");
                   1052:                else
                   1053:                        print("Rs = (Rs << %d) | Rd\n", pc[1]);
                   1054:                pc += 2;
                   1055:                break;
                   1056:                
                   1057:        case Ozero:
                   1058:                print("Rs = 0\n");
                   1059:                break;
                   1060: 
                   1061:        case ODnorS:
                   1062:                print("Rs = ~(Rd|Rs)\n");
                   1063:                break;
                   1064: 
                   1065:        case ODandnotS:
                   1066:                print("Rs = Rd & ~Rs\n");
                   1067:                break;
                   1068: 
                   1069:        case OnotS:
                   1070:                print("Rs = ~Rs\n");
                   1071:                break;
                   1072: 
                   1073:        case OnotDandS:
                   1074:                print("Rs = ~Rd & Rs\n");
                   1075:                break;
                   1076: 
                   1077:        case OnotD:
                   1078:                print("Rs = ~Rd\n");
                   1079:                break;
                   1080: 
                   1081:        case ODxorS:
                   1082:                print("Rs ^= Rd\n");
                   1083:                break;
                   1084: 
                   1085:        case ODnandS:
                   1086:                print("Rs = ~(Rd & Rs)\n");
                   1087:                break;
                   1088: 
                   1089:        case ODandS:
                   1090:                print("Rs &= Rd\n");
                   1091:                break;
                   1092: 
                   1093:        case ODxnorS:
                   1094:                print("Rs = ~(Rd ^ Rs)\n");
                   1095:                break;
                   1096: 
                   1097:        case OD:
                   1098:                print("Rs = Rd\n");
                   1099:                break;
                   1100: 
                   1101:        case ODornotS:
                   1102:                print("Rs = Rd | ~Rs\n");
                   1103:                break;
                   1104: 
                   1105:        case OnotDorS:
                   1106:                print("Rs |= ~Rd\n");
                   1107:                break;
                   1108: 
                   1109:        case ODorS:
                   1110:                print("Rs |= Rd\n");
                   1111:                break;
                   1112: 
                   1113:        case OF:
                   1114:                print("Rs = ~0L\n");
                   1115:                break;
                   1116:        }
                   1117:        goto loop;
                   1118: }
                   1119: #endif
                   1120: 

unix.superglobalmegacorp.com

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