|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.