xref: /OK3568_Linux_fs/external/xserver/miext/shadow/c2p_core.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *  Fast C2P (Chunky-to-Planar) Conversion
3  *
4  *  NOTES:
5  *    - This code was inspired by Scout's C2P tutorial
6  *    - It assumes to run on a big endian system
7  *
8  *  Copyright © 2003-2008 Geert Uytterhoeven
9  *
10  *  Permission is hereby granted, free of charge, to any person obtaining a
11  *  copy of this software and associated documentation files (the "Software"),
12  *  to deal in the Software without restriction, including without limitation
13  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  *  and/or sell copies of the Software, and to permit persons to whom the
15  *  Software is furnished to do so, subject to the following conditions:
16  *
17  *  The above copyright notice and this permission notice (including the next
18  *  paragraph) shall be included in all copies or substantial portions of the
19  *  Software.
20  *
21  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  *  DEALINGS IN THE SOFTWARE.
28  */
29 
30 
31     /*
32      *  Basic transpose step
33      */
34 
_transp(CARD32 d[],unsigned int i1,unsigned int i2,unsigned int shift,CARD32 mask)35 static inline void _transp(CARD32 d[], unsigned int i1, unsigned int i2,
36                            unsigned int shift, CARD32 mask)
37 {
38     CARD32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
39 
40     d[i1] ^= t;
41     d[i2] ^= t << shift;
42 }
43 
44 
c2p_unsupported(void)45 static inline void c2p_unsupported(void) {
46     BUG_WARN(1);
47 }
48 
get_mask(unsigned int n)49 static inline CARD32 get_mask(unsigned int n)
50 {
51     switch (n) {
52     case 1:
53         return 0x55555555;
54 
55     case 2:
56         return 0x33333333;
57 
58     case 4:
59         return 0x0f0f0f0f;
60 
61     case 8:
62         return 0x00ff00ff;
63 
64     case 16:
65         return 0x0000ffff;
66     }
67 
68     c2p_unsupported();
69     return 0;
70 }
71 
72 
73     /*
74      *  Transpose operations on 8 32-bit words
75      */
76 
transp8(CARD32 d[],unsigned int n,unsigned int m)77 static inline void transp8(CARD32 d[], unsigned int n, unsigned int m)
78 {
79     CARD32 mask = get_mask(n);
80 
81     switch (m) {
82     case 1:
83         /* First n x 1 block */
84         _transp(d, 0, 1, n, mask);
85         /* Second n x 1 block */
86         _transp(d, 2, 3, n, mask);
87         /* Third n x 1 block */
88         _transp(d, 4, 5, n, mask);
89         /* Fourth n x 1 block */
90         _transp(d, 6, 7, n, mask);
91         return;
92 
93     case 2:
94         /* First n x 2 block */
95         _transp(d, 0, 2, n, mask);
96         _transp(d, 1, 3, n, mask);
97         /* Second n x 2 block */
98         _transp(d, 4, 6, n, mask);
99         _transp(d, 5, 7, n, mask);
100         return;
101 
102     case 4:
103         /* Single n x 4 block */
104         _transp(d, 0, 4, n, mask);
105         _transp(d, 1, 5, n, mask);
106         _transp(d, 2, 6, n, mask);
107         _transp(d, 3, 7, n, mask);
108         return;
109     }
110 
111     c2p_unsupported();
112 }
113 
114 
115     /*
116      *  Transpose operations on 4 32-bit words
117      */
118 
transp4(CARD32 d[],unsigned int n,unsigned int m)119 static inline void transp4(CARD32 d[], unsigned int n, unsigned int m)
120 {
121     CARD32 mask = get_mask(n);
122 
123     switch (m) {
124     case 1:
125         /* First n x 1 block */
126         _transp(d, 0, 1, n, mask);
127         /* Second n x 1 block */
128         _transp(d, 2, 3, n, mask);
129         return;
130 
131     case 2:
132         /* Single n x 2 block */
133         _transp(d, 0, 2, n, mask);
134         _transp(d, 1, 3, n, mask);
135         return;
136     }
137 
138     c2p_unsupported();
139 }
140 
141 
142     /*
143      *  Transpose operations on 4 32-bit words (reverse order)
144      */
145 
transp4x(CARD32 d[],unsigned int n,unsigned int m)146 static inline void transp4x(CARD32 d[], unsigned int n, unsigned int m)
147 {
148     CARD32 mask = get_mask(n);
149 
150     switch (m) {
151     case 2:
152         /* Single n x 2 block */
153         _transp(d, 2, 0, n, mask);
154         _transp(d, 3, 1, n, mask);
155         return;
156     }
157 
158     c2p_unsupported();
159 }
160 
161 
162     /*
163      *  Transpose operations on 2 32-bit words
164      */
165 
transp2(CARD32 d[],unsigned int n)166 static inline void transp2(CARD32 d[], unsigned int n)
167 {
168     CARD32 mask = get_mask(n);
169 
170     /* Single n x 1 block */
171     _transp(d, 0, 1, n, mask);
172     return;
173 }
174 
175 
176     /*
177      *  Transpose operations on 2 32-bit words (reverse order)
178      */
179 
transp2x(CARD32 d[],unsigned int n)180 static inline void transp2x(CARD32 d[], unsigned int n)
181 {
182     CARD32 mask = get_mask(n);
183 
184     /* Single n x 1 block */
185     _transp(d, 1, 0, n, mask);
186     return;
187 }
188