1 /* 2 * Derived from X11R4 3 */ 4 5 /* the following notes use the following conventions: 6 SCREEN LEFT SCREEN RIGHT 7 in this file and maskbits.c, left and right refer to screen coordinates, 8 NOT bit numbering in registers. 9 10 starttab[n] 11 bits[0,n-1] = 0 bits[n,31] = 1 12 endtab[n] = 13 bits[0,n-1] = 1 bits[n,31] = 0 14 15 maskbits(x, w, startmask, endmask, nlw) 16 for a span of width w starting at position x, returns 17 a mask for ragged bits at start, mask for ragged bits at end, 18 and the number of whole longwords between the ends. 19 20 */ 21 22 #define maskbits(x, w, startmask, endmask, nlw) \ 23 startmask = starttab[(x)&0x1f]; \ 24 endmask = endtab[((x)+(w)) & 0x1f]; \ 25 if (startmask) \ 26 nlw = (((w) - (32 - ((x)&0x1f))) >> 5); \ 27 else \ 28 nlw = (w) >> 5; 29 30 #define FASTGETBITS(psrc, x, w, dst) \ 31 asm ("bfextu %3{%1:%2},%0" \ 32 : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc))) 33 34 #define FASTPUTBITS(src, x, w, pdst) \ 35 asm ("bfins %3,%0{%1:%2}" \ 36 : "=o" (*(char *)(pdst)) \ 37 : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst))) 38 39 #define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \ 40 { \ 41 register unsigned int _tmpsrc, _tmpdst; \ 42 FASTGETBITS(pdst, dstbit, width, _tmpdst); \ 43 FASTGETBITS(psrc, srcbit, width, _tmpsrc); \ 44 DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \ 45 FASTPUTBITS(_tmpdst, dstbit, width, pdst); \ 46 } 47 48 #define getandputrop0(psrc, srcbit, width, pdst, rop) \ 49 getandputrop(psrc, srcbit, 0, width, pdst, rop) 50 51 #define getunalignedword(psrc, x, dst) { \ 52 register int _tmp; \ 53 FASTGETBITS(psrc, x, 32, _tmp); \ 54 dst = _tmp; \ 55 } 56 57 #define fnCLEAR(src, dst) (0) 58 #define fnCOPY(src, dst) (src) 59 #define fnXOR(src, dst) (src ^ dst) 60 #define fnCOPYINVERTED(src, dst)(~src) 61 62 #define DoRop(result, alu, src, dst) \ 63 { \ 64 if (alu == RR_COPY) \ 65 result = fnCOPY (src, dst); \ 66 else \ 67 switch (alu) \ 68 { \ 69 case RR_CLEAR: \ 70 result = fnCLEAR (src, dst); \ 71 break; \ 72 case RR_XOR: \ 73 result = fnXOR (src, dst); \ 74 break; \ 75 case RR_COPYINVERTED: \ 76 result = fnCOPYINVERTED (src, dst); \ 77 break; \ 78 } \ 79 } 80