Commit | Line | Data |
---|---|---|
9acfa6cd MH |
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 | } |