|
|
1.1 root 1: /*
2: * C version for byte-at-a-time architectures
3: * (those with big-endian bit order, little endian byte order).
4: * See comments at beginning of gbitblt.c and bbc.h.
5: * The converting bitblt changes considerably, so that Ru is
6: * no longer needed in the abstract machine.
7: */
8:
9: #define WBITS 8
10: #define LWBITS 3
11: #define W2L 4
12: #define WMASK 0xFF
13: #define BYTEREV
14: typedef uchar *WType;
15:
16: typedef long Type;
17:
18: enum
19: {
20: field, /* arg = field mask */
21: lsha_RsRt,
22: lshb_RsRt,
23: lsh_RsRd, /* arg = shift amount */
24: lsh_RtRt, /* arg = shift amount */
25: lsha_RtRt,
26: rsha_RsRt,
27: rshb_RsRt,
28: orlsha_RsRt,
29: orlshb_RsRt,
30: orlsh_RsRd, /* arg = shift amount */
31: orrsha_RsRt,
32: orrshb_RsRt,
33: or_RsRd,
34: add_As, /* arg = add amount */
35: add_Ad, /* arg = add amount */
36: initsd, /* arg1 = value for As; arg2 = value for Ad */
37: ilabel, /* arg = inner loop count value for Ri */
38: olabel, /* arg = outer loop count value for Ro */
39: iloop, /* arg = pointer to beginning of inner loop */
40: oloop, /* arg = pointer to beginning of outer loop */
41: rts,
42: load_Rs_P,
43: load_Rt_P,
44: loador_Rt_P,
45: load_Rd_D,
46: load_Rs_D,
47: load_Rt_D,
48: load_Rd,
49: load_Rs,
50: load_Rt,
51: fetch_Rd_P,
52: fetch_Rd_D,
53: fetch_Rd,
54: store_Rs_P,
55: store_Rs_D,
56: store_Rs,
57: inittab, /* arg1 = table addr; arg2 = entry size (bytes) */
58: initsh, /* arg1 = shift amount a, arg2 = shift amount b */
59: table_RdRt, /* arg1 = offset, arg2 = nbits */
60: table_RsRt, /* arg1 = offset, arg2 = nbits */
61: assemble, /* arg1 = offset, arg2 = nbits */
62: assemblex, /* arg1 = offset, arg2 = nbits */
63: Ozero,
64: ODnorS,
65: ODandnotS,
66: OnotS,
67: OnotDandS,
68: OnotD,
69: ODxorS,
70: ODnandS,
71: ODandS,
72: ODxnorS,
73: OD,
74: ODornotS,
75: OnotDorS,
76: ODorS,
77: OF,
78: };
79:
80: /*
81: * Macros for assembling the operations of the abstract machine.
82: * Each assumes that Type *p points to the next location where
83: * an instruction should be assembled. The macros may also make
84: * use of these other variable values:
85: *
86: * tab value of AT register in abstract machine
87: * osiz value of osiz register in abstract machine
88: * sha value of sha register in abstract machine
89: * shb value of shb register in abstract machine
90: *
91: * Furthermore, there is a long called tmp which can be used for
92: * the duration of any macro.
93: *
94: * For the most part, the macros required are the same as the
95: * operations in the abstract machine (without a leading O,
96: * or with a lowercase initial letter). However, instead of
97: * macros for the bitblt opcodes Ozero, ..., OF, there is a
98: * macro called Emitop, which can use implicit arguments
99: * fi and fin (see Emitop, below).
100: *
101: * Some of the load macros take an argument f, which will be 1
102: * if the result of the load will be used by the next instruction.
103: * (Some architectures will require a Noop to be emitted when
104: * f is 1.)
105: *
106: * Finally, two other required macros are Extrainit, which can
107: * be used to do any implementation-specific initialization,
108: * and Execandfree(start,onstack), which must actually execute
109: * the compiled program and free the memory. If onstack is
110: * true, the program was compiled into a local array, so no
111: * memory need be freed. Otherwise, the space was obtained with
112: * bbmalloc, and must be freed by bbfree.
113: */
114:
115: #define Ofield(c) *p++ = field; *p++ = (c)
116: #define Olsha_RsRt *p++ = lsha_RsRt
117: #define Olshb_RsRt *p++ = lshb_RsRt
118: #define Olsh_RsRd(c) *p++ = lsh_RsRd; *p++ = (c)
119: #define Olsh_RtRt(c) *p++ = lsh_RtRt; *p++ = (c)
120: #define Olsha_RtRt *p++ = lsha_RtRt
121: #define Olsha_RtRu /* Ru not needed */
122: #define Olshb_RtRu /* Ru not needed */
123: #define Orsha_RsRt *p++ = rsha_RsRt
124: #define Orshb_RsRt *p++ = rshb_RsRt
125: #define Orsha_RtRu /* Ru not needed */
126: #define Orshb_RtRu /* Ru not needed */
127: #define Oorlsha_RsRt *p++ = orlsha_RsRt
128: #define Oorlshb_RsRt *p++ = orlshb_RsRt
129: #define Oorlsh_RsRd(c) *p++ = orlsh_RsRd; *p++ = (c)
130: #define Oorrsha_RsRt *p++ = orrsha_RsRt
131: #define Oorrshb_RsRt *p++ = orrshb_RsRt
132: #define Oorrsha_RtRu /* Ru not needed */
133: #define Oorrshb_RtRu /* Ru not needed */
134: #define Oor_RsRd *p++ = or_RsRd
135: #define Add_As(c) *p++ = add_As; *p++ = (c)
136: #define Add_Ad(c) *p++ = add_Ad; *p++ = (c)
137: #define Initsd(s,d) *p++ = initsd; *p++ = ((ulong)(s)); *p++ = ((ulong)(d))
138: #define Initsh(a,b) *p++ = initsh; *p++ = (a); *p++ = (b)
139: #define Extrainit
140: #define Ilabel(c) *p++ = ilabel; *p++ = (c)
141: #define Olabel(c) *p++ = olabel; *p++ = (c)
142: #define Iloop(lp) *p++ = iloop; *p++ = ((ulong)(lp))
143: #define Oloop(lp) *p++ = oloop; *p++ = ((ulong)(lp))
144: #define Orts *p++ = rts
145: #define Load_Rs_P *p++ = load_Rs_P
146: #define Load_Rt_P *p++ = load_Rt_P
147: #define Loadzx_Rt_P *p++ = load_Rt_P
148: #define Loador_Rt_P *p++ = loador_Rt_P
149: #define Load_Ru_P /* Ru not needed */
150: #define Load_Rd_D(f) *p++ = load_Rd_D
151: #define Load_Rs_D(f) *p++ = load_Rs_D
152: #define Load_Rt_D(f) *p++ = load_Rt_D
153: #define Loadzx_Rt_D(f) *p++ = load_Rt_D
154: #define Load_Rd(f) *p++ = load_Rd
155: #define Load_Rs(f) *p++ = load_Rs
156: #define Load_Rt(f) *p++ = load_Rt
157: #define Loadzx_Rt(f) *p++ = load_Rt
158: #define Fetch_Rd_P(f) *p++ = fetch_Rd_P
159: #define Fetch_Rd_D(f) *p++ = fetch_Rd_D
160: #define Fetch_Rd(f) *p++ = fetch_Rd
161: #define Store_Rs_P *p++ = store_Rs_P
162: #define Store_Rs_D *p++ = store_Rs_D
163: #define Store_Rs *p++ = store_Rs
164: #define Nop
165: #define Inittab(t,s) *p++ = inittab; *p++ = ((ulong)(t)); *p++ = (s)
166: #define Table_RdRt(o,n,l) *p++ = table_RdRt; *p++ = (o); *p++ = (n)
167: #define Table_RsRt(o,n,l) *p++ = table_RsRt; *p++ = (o); *p++ = (n)
168: #define Assemble(o,n) *p++ = assemble; *p++ = (o); *p++ = (n)
169: #define Assemblex(o,n) *p++ = assemble; *p++ = (o); *p++ = (n)
170:
171: #define Execandfree(memstart,onstack) \
172: interpret(memstart); \
173: if(!onstack) \
174: bbfree(memstart, (p-memstart) * sizeof(Type));
175:
176:
177: /*
178: * Emitop can assume that fi points at &fstr[op].instr, and
179: * that fin contains fstr[op].n, where op is the desired
180: * bitblt opcode as declared in gnot.h
181: */
182:
183: #define Emitop if(fin) *p++ = *fi;
184:
185: typedef struct Fstr
186: {
187: char fetchs;
188: char fetchd;
189: short n;
190: Type instr[1];
191: } Fstr;
192:
193: Fstr fstr[16] =
194: {
195: [0] 0,0,1, /* Zero */
196: {Ozero},
197:
198: [1] 1,1,1, /* DnorS */
199: {ODnorS},
200:
201: [2] 1,1,1, /* DandnotS */
202: {ODandnotS},
203:
204: [3] 1,0,1, /* notS */
205: {OnotS},
206:
207: [4] 1,1,1, /* notDandS */
208: {OnotDandS},
209:
210: [5] 0,1,1, /* notD */
211: {OnotD},
212:
213: [6] 1,1,1, /* DxorS */
214: {ODxorS},
215:
216: [7] 1,1,1, /* DnandS */
217: {ODnandS},
218:
219: [8] 1,1,1, /* DandS */
220: {ODandS},
221:
222: [9] 1,1,1, /* DxnorS */
223: {ODxnorS},
224:
225: [10] 0,1,1, /* D */
226: {OD},
227:
228: [11] 1,1,1, /* DornotS */
229: {ODornotS},
230:
231: [12] 1,0,0, /* S */
232: {0},
233:
234: [13] 1,1,1, /* notDorS */
235: {OnotDorS},
236:
237: [14] 1,1,1, /* DorS */
238: {ODorS},
239:
240: [15] 0,0,1, /* F */
241: {OF},
242: };
243:
244: #include "tabs.h"
245:
246: static uchar *tabs[4][4] =
247: {
248: { 0, (uchar*)tab01b, 0, (uchar*)tab03b},
249: {(uchar*)tab10b, 0, 0, 0},
250: { 0, 0, 0, 0},
251: {(uchar*)tab30b, 0, 0, 0},
252: };
253:
254: static uchar tabosiz[4][4] = /* size in bytes of entries */
255: {
256: { 0, 1, 0, 1},
257: { 1, 0, 0, 0},
258: { 0, 0, 0, 0},
259: { 1, 0, 0, 0},
260: };
261:
262: enum {
263: Progmax = 2000, /* max number of words in a bitblt prog */
264: Progmaxnoconv = 200, /* max number of words when no conversion */
265: };
266:
267: static void
268: interpret(Type *pc)
269: {
270: WType As, Ad;
271: ulong Rs, Rd, Rt;
272: long Ri, Ro;
273: uchar *AT;
274: int osiz, sha, shb, tmp;
275:
276: #ifdef TEST
277: WType Aslow, Ashigh, Adlow, Adhigh;
278: void prprog(void);
279:
280: Rs = lrand();
281: Rd = lrand();
282: Rt = lrand();
283: Ri = lrand();
284: Ro = lrand();
285: sha = lrand();
286: shb = lrand();
287: As = 0;
288: Ad = 0;
289: AT = 0;
290: Aslow = (WType)gaddr(cursm, curr.min);
291: Ashigh = (WType)gaddr(cursm, sub(curr.max, Pt(1,1)));
292: Adlow = (WType)gaddr(curdm, curpt);
293: Adhigh = (WType)gaddr(curdm, sub(add(curpt, sub(curr.max,curr.min)),Pt(1,1)));
294: #endif
295:
296: loop:
297: #ifdef TEST
298: switch(*pc) {
299: case load_Rs_P:
300: case load_Rt_P:
301: case load_Rd:
302: case load_Rs:
303: case load_Rt:
304: if(As < Aslow || As > Ashigh+3){
305: print("load from bad As %ux\n", As);
306: errplace:
307: print("src bitmap base %ux zero %d width %d r %d %d %d %d\n",
308: cursm->base, cursm->zero, cursm->width,
309: cursm->r.min.x, cursm->r.min.y,
310: cursm->r.max.x, cursm->r.max.y);
311: print("dst bitmap base %ux zero %d width %d r %d %d %d %d\n",
312: curdm->base, curdm->zero, curdm->width,
313: curdm->r.min.x, curdm->r.min.y,
314: curdm->r.max.x, curdm->r.max.y);
315: print("p %d %d r %d %d %d %d f %d\n",
316: curpt.x, curpt.y, curr.min.x, curr.min.y,
317: curr.max.x, curr.max.y, curf);
318: prprog();
319: exits("fail");
320: }
321: break;
322: case load_Rd_D:
323: case load_Rs_D:
324: case load_Rt_D:
325: if(As-1 < Aslow || As-1 > Ashigh+3){
326: print("load from bad As-1 %ux\n", As-1);
327: goto errplace;
328: }
329: break;
330: case fetch_Rd_P:
331: case fetch_Rd:
332: if(Ad < Adlow || Ad > Adhigh+3){
333: print("fetch from bad Ad %ux\n", Ad);
334: goto errplace;
335: }
336: break;
337: case store_Rs_P:
338: case store_Rs:
339: if(Ad < Adlow || Ad > Adhigh+3){
340: print("store to bad Ad %ux\n", Ad);
341: goto errplace;
342: }
343: break;
344: case fetch_Rd_D:
345: case store_Rs_D:
346: if(Ad-1 < Adlow || Ad-1 > Adhigh+3){
347: print("fetch from bad Ad-1 %ux\n", Ad-1);
348: prprog();
349: }
350: break;
351: }
352: #endif
353: switch(*pc++) {
354: default:
355: #ifdef TEST
356: print("unknown opcode %d\n", pc[-1]);
357: goto errplace;
358: #else
359: return;
360: #endif
361: case field:
362: /* Rs gets Rd where mask bits are 0s, Rs where mask bits are 1s */
363: Rs = ((Rs ^ Rd) & *pc++) ^ Rd;
364: break;
365:
366: case lsha_RsRt:
367: Rs = Rt << sha;
368: break;
369:
370: case lshb_RsRt:
371: Rs = Rt << shb;
372: break;
373:
374: case lsh_RsRd:
375: Rs = Rd << *pc++;
376: break;
377:
378: case lsh_RtRt: /* arg = shift amount */
379: Rt <<= *pc++;
380: break;
381:
382: case lsha_RtRt:
383: Rt <<= sha;
384: break;
385:
386: case rsha_RsRt:
387: Rs = Rt >> sha;
388: break;
389:
390: case rshb_RsRt:
391: Rs = Rt >> shb;
392: break;
393:
394: case orlsha_RsRt:
395: Rs |= Rt << sha;
396: break;
397:
398: case orlshb_RsRt:
399: Rs |= Rt << shb;
400: break;
401:
402: case orlsh_RsRd: /* arg = shift amount */
403: Rs |= Rd << *pc++;
404: break;
405:
406: case orrsha_RsRt:
407: Rs |= Rt >> sha;
408: break;
409:
410: case orrshb_RsRt:
411: Rs |= Rt >> shb;
412: break;
413:
414: case or_RsRd:
415: Rs |= Rd;
416: break;
417:
418: case add_As:
419: As = (WType)((char*)As + (long)*pc++);
420: break;
421:
422: case add_Ad:
423: Ad = (WType)((char*)Ad + (long)*pc++);
424: break;
425:
426: case initsd:
427: As = (WType)pc[0];
428: Ad = (WType)pc[1];
429: pc += 2;
430: break;
431:
432: case ilabel:
433: /* initialize inner loop count */
434: Ri = *pc++;
435: break;
436:
437: case olabel:
438: /* initialize outer loop count */
439: Ro = *pc++;
440: break;
441:
442: case iloop:
443: /* decrement inner loop count, loop back if still positive */
444: Ri--;
445: if(Ri > 0) {
446: pc = (Type*)pc[0];
447: break;
448: }
449: pc++;
450: break;
451:
452: case oloop:
453: /* decrement outer loop count, loop back if still positive */
454: Ro--;
455: if(Ro > 0) {
456: pc = (Type*)pc[0];
457: break;
458: }
459: pc++;
460: break;
461:
462: case rts:
463: return;
464:
465: case load_Rs_P:
466: Rs = *As++;
467: break;
468:
469: case load_Rt_P:
470: Rt = *As++;
471: break;
472:
473: case loador_Rt_P:
474: Rt |= *As++;
475: break;
476:
477: case load_Rd_D:
478: Rd = *--As;
479: break;
480:
481: case load_Rs_D:
482: Rs = *--As;
483: break;
484:
485: case load_Rt_D:
486: Rt = *--As;
487: break;
488:
489: case load_Rd:
490: Rd = *As;
491: break;
492:
493: case load_Rs:
494: Rs = *As;
495: break;
496:
497: case load_Rt:
498: Rt = *As;
499: break;
500:
501: case fetch_Rd_P:
502: Rd = *Ad++;
503: break;
504:
505: case fetch_Rd_D:
506: Rd = *--Ad;
507: break;
508:
509: case fetch_Rd:
510: Rd = *Ad;
511: break;
512:
513: case store_Rs_P:
514: *Ad++ = Rs;
515: break;
516:
517: case store_Rs_D:
518: *--Ad = Rs;
519: break;
520:
521: case store_Rs:
522: *Ad = Rs;
523: break;
524:
525: case inittab:
526: AT = (uchar*)pc[0];
527: osiz = (long)pc[1];
528: pc += 2;
529: break;
530:
531: case initsh:
532: sha = (long)pc[0];
533: shb = (long)pc[1];
534: pc += 2;
535: break;
536:
537: case table_RdRt:
538: /*
539: * Starting at offset arg1 in Rt, take arg2 bits,
540: * and use it to look up in table AT, putting answer in Rd.
541: * osiz is always 1 for this bitblt
542: */
543: tmp = (long)pc[1];
544: Rd = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
545: Rd = AT[Rd];
546: pc += 2;
547: break;
548:
549: case table_RsRt:
550: /* like table_RdRt, but answer goes in Rs */
551: tmp = (long)pc[1];
552: Rs = (Rt >> (32-((long)pc[0]+tmp))) & ((1<<tmp)-1);
553: Rs = AT[Rs];
554: pc += 2;
555: break;
556:
557: case assemble:
558: /*
559: * Move low arg2 bits of Rd into offset arg1 in Rs.
560: * Can assume that high bits of Rd are zero,
561: * and target field of Rs is zero if offset != 0
562: */
563: tmp = (long)pc[0];
564: if(tmp == 0)
565: Rs = Rd << (8-pc[1]);
566: else
567: Rs |= Rd << (8-(tmp+pc[1]));
568: pc += 2;
569: break;
570:
571: case assemblex:
572: /*
573: * Like assemble, but fields will be moved into
574: * proper position by later Assemblex's
575: */
576: tmp = (long)pc[0];
577: if(tmp == 0)
578: Rs = Rd;
579: else
580: Rs = (Rs << pc[1]) | Rd;
581: pc += 2;
582: break;
583:
584: case Ozero:
585: Rs = 0;
586: break;
587:
588: case ODnorS:
589: Rs = ~(Rd|Rs);
590: break;
591:
592: case ODandnotS:
593: Rs = Rd & ~Rs;
594: break;
595:
596: case OnotS:
597: Rs = ~Rs;
598: break;
599:
600: case OnotDandS:
601: Rs = ~Rd & Rs;
602: break;
603:
604: case OnotD:
605: Rs = ~Rd;
606: break;
607:
608: case ODxorS:
609: Rs ^= Rd;
610: break;
611:
612: case ODnandS:
613: Rs = ~(Rd & Rs);
614: break;
615:
616: case ODandS:
617: Rs &= Rd;
618: break;
619:
620: case ODxnorS:
621: Rs = ~(Rd ^ Rs);
622: break;
623:
624: case OD:
625: Rs = Rd;
626: break;
627:
628: case ODornotS:
629: Rs = Rd | ~Rs;
630: break;
631:
632: case OnotDorS:
633: Rs |= ~Rd;
634: break;
635:
636: case ODorS:
637: Rs |= Rd;
638: break;
639:
640: case OF:
641: Rs = ~0L;
642: break;
643: }
644: goto loop;
645: }
646:
647: #ifdef TEST
648: void
649: prprog(void)
650: {
651: int osiz;
652: Type *pc;
653: pc = (Type *)mem;
654:
655: loop:
656: switch(*pc++) {
657: default:
658: print("unknown opcode %d\n", pc[-1]);
659: exits("unknown opcode");
660: case field:
661: print("Rs = ((Rs ^ Rd) & 0x%lux) ^ Rd\n", *pc++);
662: break;
663:
664: case lsha_RsRt:
665: print("Rs = Rt << sha\n");
666: break;
667:
668: case lshb_RsRt:
669: print("Rs = Rt << shb\n");
670: break;
671:
672: case lsh_RsRd:
673: print("Rs = Rd << %d\n", *pc++);
674: break;
675:
676: case lsh_RtRt:
677: print("Rt <<= %d\n", *pc++);
678: break;
679:
680: case lsha_RtRt:
681: print("Rt <<= sha\n");
682: break;
683:
684: case rsha_RsRt:
685: print("Rs = Rt >> sha\n");
686: break;
687:
688: case rshb_RsRt:
689: print("Rs = Rt >> shb\n");
690: break;
691:
692: case orlsha_RsRt:
693: print("Rs |= Rt << sha\n");
694: break;
695:
696: case orlshb_RsRt:
697: print("Rs |= Rt << shb\n");
698: break;
699:
700: case orlsh_RsRd:
701: print("Rs |= Rd << %d\n", *pc++);
702: break;
703:
704: case orrsha_RsRt:
705: print("Rs |= Rt >> sha\n");
706: break;
707:
708: case orrshb_RsRt:
709: print("Rs |= Rt >> shb\n");
710: break;
711:
712: case or_RsRd:
713: print("Rs |= Rd\n");
714: break;
715:
716: case add_As:
717: print("As += %d\n", (long)*pc++);
718: break;
719:
720: case add_Ad:
721: print("Ad += %d\n", (long)*pc++);
722: break;
723:
724: case initsd:
725: print("As = 0x%lux\n", (ulong*)pc[0]);
726: print("Ad = 0x%lux\n", (ulong*)pc[1]);
727: pc += 2;
728: break;
729:
730: case ilabel:
731: print("Ri = %d\n", *pc++);
732: break;
733:
734: case olabel:
735: print("Ro = %d\n", *pc++);
736: break;
737:
738: case iloop:
739: print("if(--Ri > 0) goto 0x%lux\n", *pc++);
740: break;
741:
742: case oloop:
743: print("if(--Ro > 0) goto 0x%lux\n", *pc++);
744: break;
745:
746: case rts:
747: print("return\n");
748: return;
749:
750: case load_Rs_P:
751: print("Rs = *As++\n");
752: break;
753:
754: case load_Rt_P:
755: print("Rt = *As++\n");
756: break;
757:
758: case loador_Rt_P:
759: print("Rt |= *As++\n");
760: break;
761:
762: case load_Rd_D:
763: print("Rd = *--As\n");
764: break;
765:
766: case load_Rs_D:
767: print("Rs = *--As\n");
768: break;
769:
770: case load_Rt_D:
771: print("Rt = *--As\n");
772: break;
773:
774: case load_Rd:
775: print("Rd = *As\n");
776: break;
777:
778: case load_Rs:
779: print("Rs = *As\n");
780: break;
781:
782: case load_Rt:
783: print("Rt = *As\n");
784: break;
785:
786: case fetch_Rd_P:
787: print("Rd = *Ad++\n");
788: break;
789:
790: case fetch_Rd_D:
791: print("Rd = *--Ad\n");
792: break;
793:
794: case fetch_Rd:
795: print("Rd = *Ad\n");
796: break;
797:
798: case store_Rs_P:
799: print("*Ad++ = Rs\n");
800: break;
801:
802: case store_Rs_D:
803: print("*--Ad = Rs\n");
804: break;
805:
806: case store_Rs:
807: print("*Ad = Rs\n");
808: break;
809:
810: case inittab:
811: print("AT = 0x%lux (%d byte entries)\n", pc[0],pc[1]);
812: osiz = pc[1];
813: pc += 2;
814: break;
815:
816: case initsh:
817: print("sha = %d\n", (long)pc[0]);
818: print("shb = %d\n", (long)pc[1]);
819: pc += 2;
820: break;
821:
822: case table_RdRt:
823: print("Rd = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
824: pc += 2;
825: break;
826:
827: case table_RsRt:
828: print("Rs = ((char*)AT)[Rt{%d..%d}]\n", pc[0], pc[0]+pc[1]-1);
829: pc += 2;
830: break;
831:
832: case assemble:
833: /*
834: * Move low arg2 bits of Rd into offset arg1 in Rs.
835: * Can assume that high bits of Rd are zero,
836: * and target field of Rs is zero if offset != 0
837: */
838: if(pc[0] == 0)
839: print("Rs = Rd << %d\n", (32-(long)pc[1]));
840: else
841: print("Rs |= Rd << %d\n", (32-((long)pc[0]+(long)pc[1])));
842: pc += 2;
843: break;
844:
845: case assemblex:
846: /*
847: * Like assemble, but fields will be moved into
848: * proper position by later Assemblex's
849: */
850: if(pc[0] == 0)
851: print("Rs = Rd\n");
852: else
853: print("Rs = (Rs << %d) | Rd\n", pc[1]);
854: pc += 2;
855: break;
856:
857: case Ozero:
858: print("Rs = 0\n");
859: break;
860:
861: case ODnorS:
862: print("Rs = ~(Rd|Rs)\n");
863: break;
864:
865: case ODandnotS:
866: print("Rs = Rd & ~Rs\n");
867: break;
868:
869: case OnotS:
870: print("Rs = ~Rs\n");
871: break;
872:
873: case OnotDandS:
874: print("Rs = ~Rd & Rs\n");
875: break;
876:
877: case OnotD:
878: print("Rs = ~Rd\n");
879: break;
880:
881: case ODxorS:
882: print("Rs ^= Rd\n");
883: break;
884:
885: case ODnandS:
886: print("Rs = ~(Rd & Rs)\n");
887: break;
888:
889: case ODandS:
890: print("Rs &= Rd\n");
891: break;
892:
893: case ODxnorS:
894: print("Rs = ~(Rd ^ Rs)\n");
895: break;
896:
897: case OD:
898: print("Rs = Rd\n");
899: break;
900:
901: case ODornotS:
902: print("Rs = Rd | ~Rs\n");
903: break;
904:
905: case OnotDorS:
906: print("Rs |= ~Rd\n");
907: break;
908:
909: case ODorS:
910: print("Rs |= Rd\n");
911: break;
912:
913: case OF:
914: print("Rs = ~0L\n");
915: break;
916: }
917: goto loop;
918: }
919: #endif
920:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.