1*91d94812Smatt /* $NetBSD: raster_op.c,v 1.19 2012/01/31 04:28:02 matt Exp $ */
2a8e925d3Spk
3a8e925d3Spk /*-
4a8e925d3Spk * Copyright (c) 1991, 1993
5a8e925d3Spk * The Regents of the University of California. All rights reserved.
6a8e925d3Spk *
7a8e925d3Spk * This code is derived from software contributed to the Computer Systems
8a8e925d3Spk * Engineering Group at Lawrence Berkeley Laboratory and to the University
9a8e925d3Spk * of California at Berkeley by Jef Poskanzer.
10a8e925d3Spk *
11a8e925d3Spk * Redistribution and use in source and binary forms, with or without
12a8e925d3Spk * modification, are permitted provided that the following conditions
13a8e925d3Spk * are met:
14a8e925d3Spk * 1. Redistributions of source code must retain the above copyright
15a8e925d3Spk * notice, this list of conditions and the following disclaimer.
16a8e925d3Spk * 2. Redistributions in binary form must reproduce the above copyright
17a8e925d3Spk * notice, this list of conditions and the following disclaimer in the
18a8e925d3Spk * documentation and/or other materials provided with the distribution.
19aad01611Sagc * 3. Neither the name of the University nor the names of its contributors
20a8e925d3Spk * may be used to endorse or promote products derived from this software
21a8e925d3Spk * without specific prior written permission.
22a8e925d3Spk *
23a8e925d3Spk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24a8e925d3Spk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25a8e925d3Spk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26a8e925d3Spk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27a8e925d3Spk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28a8e925d3Spk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29a8e925d3Spk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30a8e925d3Spk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31a8e925d3Spk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32a8e925d3Spk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33a8e925d3Spk * SUCH DAMAGE.
34a8e925d3Spk *
35a8e925d3Spk * @(#)raster_op.c 8.1 (Berkeley) 6/11/93
36a8e925d3Spk */
37a8e925d3Spk
38a8e925d3Spk /*
39a8e925d3Spk * Bitblit routine for raster library.
40a8e925d3Spk *
41a8e925d3Spk * This raster-op is machined to exacting tolerances by skilled native
42a8e925d3Spk * craftsmen with pride in their work.
43a8e925d3Spk *
44a8e925d3Spk * The various cases are broken down like this:
45a8e925d3Spk *
46a8e925d3Spk * src required
47a8e925d3Spk * 1-bit to 1-bit
4823795512Sdrochner * 1-bit to 2-bits
49d617933eSscottr * 1-bit to 4-bits
50a8e925d3Spk * 1-bit to 8-bits
519d326d48Sdbj * 1-bit to 16-bits
5223795512Sdrochner * 2-bits to 2-bits
53d617933eSscottr * 2-bits to 4-bits (not implemented)
549d326d48Sdbj * 2-bits to 8-bits (not implemented)
559d326d48Sdbj * 2-bits to 16-bits (not implemented)
56d617933eSscottr * 4-bits to 4-bits
57d617933eSscottr * 4-bits to 8-bits (not implemented)
58d617933eSscottr * 4-bits to 16-bits (not implemented)
59a8e925d3Spk * 8-bits to 8-bits
609d326d48Sdbj * 8-bits to 16-bits (not implemented)
619d326d48Sdbj * 16-bits to 16-bits
62a8e925d3Spk * no src required
63a8e925d3Spk * 1-bit no-src
6423795512Sdrochner * 2-bits no-src
65a8e925d3Spk * 8-bits no-src
669d326d48Sdbj * 16-bits no-src
67a8e925d3Spk */
68a8e925d3Spk
697ba10b35Slukem #include <sys/cdefs.h>
70*91d94812Smatt __KERNEL_RCSID(0, "$NetBSD: raster_op.c,v 1.19 2012/01/31 04:28:02 matt Exp $");
717ba10b35Slukem
72a8e925d3Spk #include <sys/types.h>
73540ab1b8Scgd #ifdef _KERNEL
749d326d48Sdbj #include "opt_rcons.h"
759a37177dSdeberg #include <dev/rcons/raster.h>
76540ab1b8Scgd #else
77540ab1b8Scgd #include "raster.h"
78540ab1b8Scgd #endif
79a8e925d3Spk
80a8e925d3Spk /* CONFIGURE: To save on executable size, you can configure out the seldom-used
81a8e925d3Spk ** logical operations. With this variable set, the only operations implemented
82a8e925d3Spk ** are: RAS_SRC, RAS_CLEAR, RAS_SET, RAS_INVERT, RAS_XOR, RAS_INVERTSRC.
83a8e925d3Spk */
84a8e925d3Spk #ifdef _KERNEL
85a8e925d3Spk #define PARTIAL_LOGICAL_OPS
86a8e925d3Spk #endif
87a8e925d3Spk
88a8e925d3Spk /* CONFIGURE: bcopy() is supposed to be the ultimately fastest way to move
89a8e925d3Spk ** bytes, overlapping or not, ignoring the startup cost. Unfortunately
90a8e925d3Spk ** this is not true on some systems. For example, on a Sun 3 running
91a8e925d3Spk ** SunOS 3.5, bcopy() is about five times slower than a simple for loop
92a8e925d3Spk ** on overlapping copies. And on a 4.1.1 SPARC, bcopy() is about 2/3rds
93a8e925d3Spk ** as fast on backwards overlaps. So, only define this if your bcopy is ok.
94a8e925d3Spk */
95a8e925d3Spk #undef BCOPY_FASTER
96a8e925d3Spk
97a8e925d3Spk /* End of configurable definitions. */
98a8e925d3Spk
99a8e925d3Spk
100a8e925d3Spk /* Definitions. */
101a8e925d3Spk
102a8e925d3Spk /* Raster-op macros. These encapsulate the switch statements and so make
103a8e925d3Spk ** the source code 16 times smaller. The pre and pst args are code
104a8e925d3Spk ** fragments to put before and after the assignment in each case. They
105a8e925d3Spk ** can be the beginning and end of a loop. If the pst fragment includes a
106a8e925d3Spk ** masked assignment, for example to handle the left or right edge cases,
107a8e925d3Spk ** a good optimizing compiler will simplify the boolean expressions very
108a8e925d3Spk ** nicely - both cc and gcc on the SPARC will do this.
109a8e925d3Spk */
110a8e925d3Spk
111a8e925d3Spk #ifndef PARTIAL_LOGICAL_OPS
112a8e925d3Spk
113a8e925d3Spk #define ROP_DST(op,pre,d,pst) \
114a8e925d3Spk switch ( op ) \
115a8e925d3Spk { \
116a8e925d3Spk case RAS_CLEAR: \
117a8e925d3Spk pre \
118a8e925d3Spk (d) = 0; \
119a8e925d3Spk pst \
120a8e925d3Spk break; \
121a8e925d3Spk case RAS_INVERT: \
122a8e925d3Spk pre \
123a8e925d3Spk (d) = ~(d); \
124a8e925d3Spk pst \
125a8e925d3Spk break; \
126a8e925d3Spk case RAS_DST: \
127a8e925d3Spk /* noop */ \
128a8e925d3Spk break; \
129a8e925d3Spk case RAS_SET: \
130a8e925d3Spk pre \
131a8e925d3Spk (d) = ~0; \
132a8e925d3Spk pst \
133a8e925d3Spk break; \
134a8e925d3Spk default: \
135a8e925d3Spk return -1; \
136a8e925d3Spk }
137a8e925d3Spk
138a8e925d3Spk #define ROP_DSTCOLOR(op,pre,d,c,pst) \
139a8e925d3Spk switch ( op ) \
140a8e925d3Spk { \
141a8e925d3Spk case RAS_CLEAR: \
142a8e925d3Spk pre \
143a8e925d3Spk (d) = 0; \
144a8e925d3Spk pst \
145a8e925d3Spk break; \
146a8e925d3Spk case RAS_INVERT: \
147a8e925d3Spk pre \
148a8e925d3Spk (d) = ~(d); \
149a8e925d3Spk pst \
150a8e925d3Spk break; \
151a8e925d3Spk case RAS_DST: \
152a8e925d3Spk /* noop */ \
153a8e925d3Spk break; \
154a8e925d3Spk case RAS_SET: \
155a8e925d3Spk pre \
156a8e925d3Spk (d) = (c); \
157a8e925d3Spk pst \
158a8e925d3Spk break; \
159a8e925d3Spk default: \
160a8e925d3Spk return -1; \
161a8e925d3Spk }
162a8e925d3Spk
163a8e925d3Spk #define ROP_SRCDST(op,pre,s,d,pst) \
164a8e925d3Spk switch ( op ) \
165a8e925d3Spk { \
166a8e925d3Spk case RAS_NOTOR: \
167a8e925d3Spk pre \
168a8e925d3Spk (d) = ~( (s) | (d) ); \
169a8e925d3Spk pst \
170a8e925d3Spk break; \
171a8e925d3Spk case RAS_NOTSRC_AND_DST: \
172a8e925d3Spk pre \
173a8e925d3Spk (d) = ~(s) & (d); \
174a8e925d3Spk pst \
175a8e925d3Spk break; \
176a8e925d3Spk case RAS_INVERTSRC: \
177a8e925d3Spk pre \
178a8e925d3Spk (d) = ~(s); \
179a8e925d3Spk pst \
180a8e925d3Spk break; \
181a8e925d3Spk case RAS_SRC_AND_NOTDST: \
182a8e925d3Spk pre \
183a8e925d3Spk (d) = (s) & ~(d); \
184a8e925d3Spk pst \
185a8e925d3Spk break; \
186a8e925d3Spk case RAS_XOR: \
187a8e925d3Spk pre \
188a8e925d3Spk (d) = (s) ^ (d); \
189a8e925d3Spk pst \
190a8e925d3Spk break; \
191a8e925d3Spk case RAS_NOTAND: \
192a8e925d3Spk pre \
193a8e925d3Spk (d) = ~( (s) & (d) ); \
194a8e925d3Spk pst \
195a8e925d3Spk break; \
196a8e925d3Spk case RAS_AND: \
197a8e925d3Spk pre \
198a8e925d3Spk (d) = (s) & (d); \
199a8e925d3Spk pst \
200a8e925d3Spk break; \
201a8e925d3Spk case RAS_NOTXOR: \
202a8e925d3Spk pre \
203a8e925d3Spk (d) = ~( (s) ^ (d) ); \
204a8e925d3Spk pst \
205a8e925d3Spk break; \
206a8e925d3Spk case RAS_NOTSRC_OR_DST: \
207a8e925d3Spk pre \
208a8e925d3Spk (d) = ~(s) | (d); \
209a8e925d3Spk pst \
210a8e925d3Spk break; \
211a8e925d3Spk case RAS_SRC: \
212a8e925d3Spk pre \
213a8e925d3Spk (d) = (s); \
214a8e925d3Spk pst \
215a8e925d3Spk break; \
216a8e925d3Spk case RAS_SRC_OR_NOTDST: \
217a8e925d3Spk pre \
218a8e925d3Spk (d) = (s) | ~(d); \
219a8e925d3Spk pst \
220a8e925d3Spk break; \
221a8e925d3Spk case RAS_OR: \
222a8e925d3Spk pre \
223a8e925d3Spk (d) = (s) | (d); \
224a8e925d3Spk pst \
225a8e925d3Spk break; \
226a8e925d3Spk default: \
227a8e925d3Spk return -1; \
228a8e925d3Spk }
229a8e925d3Spk
230a8e925d3Spk #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
231a8e925d3Spk switch ( op ) \
232a8e925d3Spk { \
233a8e925d3Spk case RAS_NOTOR: \
234a8e925d3Spk pre \
235a8e925d3Spk if ( s ) \
236a8e925d3Spk (d) = ~( (c) | (d) ); \
237a8e925d3Spk else \
238a8e925d3Spk (d) = ~(d); \
239a8e925d3Spk pst \
240a8e925d3Spk break; \
241a8e925d3Spk case RAS_NOTSRC_AND_DST: \
242a8e925d3Spk pre \
243a8e925d3Spk if ( s ) \
244a8e925d3Spk (d) = ~(c) & (d); \
245a8e925d3Spk pst \
246a8e925d3Spk break; \
247a8e925d3Spk case RAS_INVERTSRC: \
248a8e925d3Spk pre \
249a8e925d3Spk if ( s ) \
250a8e925d3Spk (d) = ~(c); \
251a8e925d3Spk else \
252a8e925d3Spk (d) = ~0; \
253a8e925d3Spk pst \
254a8e925d3Spk break; \
255a8e925d3Spk case RAS_SRC_AND_NOTDST: \
256a8e925d3Spk pre \
257a8e925d3Spk if ( s ) \
258a8e925d3Spk (d) = (c) & ~(d); \
259a8e925d3Spk else \
260a8e925d3Spk (d) = 0; \
261a8e925d3Spk pst \
262a8e925d3Spk break; \
263a8e925d3Spk case RAS_XOR: \
264a8e925d3Spk pre \
265a8e925d3Spk if ( s ) \
266a8e925d3Spk (d) = (c) ^ (d); \
267a8e925d3Spk pst \
268a8e925d3Spk break; \
269a8e925d3Spk case RAS_NOTAND: \
270a8e925d3Spk pre \
271a8e925d3Spk if ( s ) \
272a8e925d3Spk (d) = ~( (c) & (d) ); \
273a8e925d3Spk else \
274a8e925d3Spk (d) = ~0; \
275a8e925d3Spk pst \
276a8e925d3Spk break; \
277a8e925d3Spk case RAS_AND: \
278a8e925d3Spk pre \
279a8e925d3Spk if ( s ) \
280a8e925d3Spk (d) = (c) & (d); \
281a8e925d3Spk else \
282a8e925d3Spk (d) = 0; \
283a8e925d3Spk pst \
284a8e925d3Spk break; \
285a8e925d3Spk case RAS_NOTXOR: \
286a8e925d3Spk pre \
287a8e925d3Spk if ( s ) \
288a8e925d3Spk (d) = ~( (c) ^ (d) ); \
289a8e925d3Spk else \
290a8e925d3Spk (d) = ~(d); \
291a8e925d3Spk pst \
292a8e925d3Spk break; \
293a8e925d3Spk case RAS_NOTSRC_OR_DST: \
294a8e925d3Spk pre \
295a8e925d3Spk if ( s ) \
296a8e925d3Spk (d) = ~(c) | (d); \
297a8e925d3Spk else \
298a8e925d3Spk (d) = ~0; \
299a8e925d3Spk pst \
300a8e925d3Spk break; \
301a8e925d3Spk case RAS_SRC: \
302a8e925d3Spk pre \
303a8e925d3Spk if ( s ) \
304a8e925d3Spk (d) = (c); \
305a8e925d3Spk else \
306a8e925d3Spk (d) = 0; \
307a8e925d3Spk pst \
308a8e925d3Spk break; \
309a8e925d3Spk case RAS_SRC_OR_NOTDST: \
310a8e925d3Spk pre \
311a8e925d3Spk if ( s ) \
312a8e925d3Spk (d) = (c) | ~(d); \
313a8e925d3Spk else \
314a8e925d3Spk (d) = ~(d); \
315a8e925d3Spk pst \
316a8e925d3Spk break; \
317a8e925d3Spk case RAS_OR: \
318a8e925d3Spk pre \
319a8e925d3Spk if ( s ) \
320a8e925d3Spk (d) = (c) | (d); \
321a8e925d3Spk pst \
322a8e925d3Spk break; \
323a8e925d3Spk default: \
324a8e925d3Spk return -1; \
325a8e925d3Spk }
326a8e925d3Spk
327a8e925d3Spk #else /*PARTIAL_LOGICAL_OPS*/
328a8e925d3Spk
329a8e925d3Spk #define ROP_DST(op,pre,d,pst) \
330a8e925d3Spk switch ( op ) \
331a8e925d3Spk { \
332a8e925d3Spk case RAS_CLEAR: \
333a8e925d3Spk pre \
334a8e925d3Spk (d) = 0; \
335a8e925d3Spk pst \
336a8e925d3Spk break; \
337a8e925d3Spk case RAS_INVERT: \
338a8e925d3Spk pre \
339a8e925d3Spk (d) = ~(d); \
340a8e925d3Spk pst \
341a8e925d3Spk break; \
342a8e925d3Spk case RAS_SET: \
343a8e925d3Spk pre \
344a8e925d3Spk (d) = ~0; \
345a8e925d3Spk pst \
346a8e925d3Spk break; \
347a8e925d3Spk default: \
348a8e925d3Spk return -1; \
349a8e925d3Spk }
350a8e925d3Spk
351a8e925d3Spk #define ROP_DSTCOLOR(op,pre,d,c,pst) \
352a8e925d3Spk switch ( op ) \
353a8e925d3Spk { \
354a8e925d3Spk case RAS_CLEAR: \
355a8e925d3Spk pre \
356a8e925d3Spk (d) = 0; \
357a8e925d3Spk pst \
358a8e925d3Spk break; \
359a8e925d3Spk case RAS_INVERT: \
360a8e925d3Spk pre \
361a8e925d3Spk (d) = ~(d); \
362a8e925d3Spk pst \
363a8e925d3Spk break; \
364a8e925d3Spk case RAS_SET: \
365a8e925d3Spk pre \
366a8e925d3Spk (d) = (c); \
367a8e925d3Spk pst \
368a8e925d3Spk break; \
369a8e925d3Spk default: \
370a8e925d3Spk return -1; \
371a8e925d3Spk }
372a8e925d3Spk
373a8e925d3Spk #define ROP_SRCDST(op,pre,s,d,pst) \
374a8e925d3Spk switch ( op ) \
375a8e925d3Spk { \
376a8e925d3Spk case RAS_INVERTSRC: \
377a8e925d3Spk pre \
378a8e925d3Spk (d) = ~(s); \
379a8e925d3Spk pst \
380a8e925d3Spk break; \
381a8e925d3Spk case RAS_XOR: \
382a8e925d3Spk pre \
383a8e925d3Spk (d) = (s) ^ (d); \
384a8e925d3Spk pst \
385a8e925d3Spk break; \
386a8e925d3Spk case RAS_SRC: \
387a8e925d3Spk pre \
388a8e925d3Spk (d) = (s); \
389a8e925d3Spk pst \
390a8e925d3Spk break; \
391a8e925d3Spk default: \
392a8e925d3Spk return -1; \
393a8e925d3Spk }
394a8e925d3Spk
395a8e925d3Spk #define ROP_SRCDSTCOLOR(op,pre,s,d,c,pst) \
396a8e925d3Spk switch ( op ) \
397a8e925d3Spk { \
398a8e925d3Spk case RAS_INVERTSRC: \
399a8e925d3Spk pre \
400a8e925d3Spk if ( s ) \
401a8e925d3Spk (d) = ~(c); \
402a8e925d3Spk else \
403a8e925d3Spk (d) = ~0; \
404a8e925d3Spk pst \
405a8e925d3Spk break; \
406a8e925d3Spk case RAS_XOR: \
407a8e925d3Spk pre \
408a8e925d3Spk if ( s ) \
409a8e925d3Spk (d) = (c) ^ (d); \
410a8e925d3Spk pst \
411a8e925d3Spk break; \
412a8e925d3Spk case RAS_SRC: \
413a8e925d3Spk pre \
414a8e925d3Spk if ( s ) \
415a8e925d3Spk (d) = (c); \
416a8e925d3Spk else \
417a8e925d3Spk (d) = 0; \
418a8e925d3Spk pst \
419a8e925d3Spk break; \
420a8e925d3Spk default: \
421a8e925d3Spk return -1; \
422a8e925d3Spk }
423a8e925d3Spk
424a8e925d3Spk #endif /*PARTIAL_LOGICAL_OPS*/
425a8e925d3Spk
426a8e925d3Spk
427a8e925d3Spk /* Variables. */
428a8e925d3Spk
429a8e925d3Spk static int needsrc[16] = { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
430a8e925d3Spk /* CLEAR INVERT DST SET */
431a8e925d3Spk
432a8e925d3Spk #ifdef MSBIT_FIRST
433a8e925d3Spk
434540ab1b8Scgd u_int32_t raster_bitmask[32] = {
435a8e925d3Spk 0x80000000, 0x40000000, 0x20000000, 0x10000000,
436a8e925d3Spk 0x08000000, 0x04000000, 0x02000000, 0x01000000,
437a8e925d3Spk 0x00800000, 0x00400000, 0x00200000, 0x00100000,
438a8e925d3Spk 0x00080000, 0x00040000, 0x00020000, 0x00010000,
439a8e925d3Spk 0x00008000, 0x00004000, 0x00002000, 0x00001000,
440a8e925d3Spk 0x00000800, 0x00000400, 0x00000200, 0x00000100,
441a8e925d3Spk 0x00000080, 0x00000040, 0x00000020, 0x00000010,
442a8e925d3Spk 0x00000008, 0x00000004, 0x00000002, 0x00000001 };
443a8e925d3Spk
444a8e925d3Spk #ifdef MSBYTE_FIRST
445540ab1b8Scgd static u_int32_t leftmask[32] = {
446a8e925d3Spk 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
447a8e925d3Spk 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
448a8e925d3Spk 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
449a8e925d3Spk 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
450a8e925d3Spk 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
451a8e925d3Spk 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
452a8e925d3Spk 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
453a8e925d3Spk 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe };
454540ab1b8Scgd static u_int32_t rightmask[32] = {
455a8e925d3Spk 0x00000000, 0x00000001, 0x00000003, 0x00000007,
456a8e925d3Spk 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
457a8e925d3Spk 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
458a8e925d3Spk 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
459a8e925d3Spk 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
460a8e925d3Spk 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
461a8e925d3Spk 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
462a8e925d3Spk 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff };
4633b2862c8Spk
4643b2862c8Spk #define LSOP <<
4653b2862c8Spk #define RSOP >>
466a8e925d3Spk #endif /*MSBYTE_FIRST*/
467a8e925d3Spk
468a8e925d3Spk #else /*MSBIT_FIRST*/
469a8e925d3Spk
470540ab1b8Scgd u_int32_t raster_bitmask[32] = {
471a8e925d3Spk 0x00000001, 0x00000002, 0x00000004, 0x00000008,
472a8e925d3Spk 0x00000010, 0x00000020, 0x00000040, 0x00000080,
473a8e925d3Spk 0x00000100, 0x00000200, 0x00000400, 0x00000800,
474a8e925d3Spk 0x00001000, 0x00002000, 0x00004000, 0x00008000,
475a8e925d3Spk 0x00010000, 0x00020000, 0x00040000, 0x00080000,
476a8e925d3Spk 0x00100000, 0x00200000, 0x00400000, 0x00800000,
477a8e925d3Spk 0x01000000, 0x02000000, 0x04000000, 0x08000000,
478a8e925d3Spk 0x10000000, 0x20000000, 0x40000000, 0x80000000 };
479a8e925d3Spk
480a8e925d3Spk #ifndef MSBYTE_FIRST
481540ab1b8Scgd static u_int32_t leftmask[32] = {
482a8e925d3Spk 0x00000000, 0x00000001, 0x00000003, 0x00000007,
483a8e925d3Spk 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
484a8e925d3Spk 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
485a8e925d3Spk 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
486a8e925d3Spk 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
487a8e925d3Spk 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
488a8e925d3Spk 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
489a8e925d3Spk 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff };
490540ab1b8Scgd static u_int32_t rightmask[32] = {
491a8e925d3Spk 0x00000000, 0x80000000, 0xc0000000, 0xe0000000,
492a8e925d3Spk 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000,
493a8e925d3Spk 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
494a8e925d3Spk 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000,
495a8e925d3Spk 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000,
496a8e925d3Spk 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
497a8e925d3Spk 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0,
498a8e925d3Spk 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe };
4993b2862c8Spk #define LSOP >>
5003b2862c8Spk #define RSOP <<
501a8e925d3Spk #endif /*not MSBYTE_FIRST*/
502a8e925d3Spk
503a8e925d3Spk #endif /*MSBIT_FIRST*/
504a8e925d3Spk
505a8e925d3Spk /* (The odd combinations MSBIT+~MSBYTE and ~MSBIT+MSBYTE could be added.) */
506a8e925d3Spk
507a8e925d3Spk #ifdef MSBYTE_FIRST
508540ab1b8Scgd static u_int32_t bytemask[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
50923795512Sdrochner #ifdef RCONS_2BPP
51023795512Sdrochner static u_int32_t twobitmask[16] = {
51123795512Sdrochner 0xc0000000, 0x30000000, 0x0c000000, 0x03000000,
51223795512Sdrochner 0x00c00000, 0x00300000, 0x000c0000, 0x00030000,
51323795512Sdrochner 0x0000c000, 0x00003000, 0x00000c00, 0x00000300,
51423795512Sdrochner 0x000000c0, 0x00000030, 0x0000000c, 0x00000003 };
51523795512Sdrochner #endif /* RCONS_2BPP */
516d617933eSscottr #ifdef RCONS_4BPP
517d617933eSscottr static u_int32_t fourbitmask[8] = {
518d617933eSscottr 0xf0000000, 0x0f000000,
519d617933eSscottr 0x00f00000, 0x000f0000,
520d617933eSscottr 0x0000f000, 0x00000f00,
521d617933eSscottr 0x000000f0, 0x0000000f };
522d617933eSscottr #endif /* RCONS_4BPP */
5239d326d48Sdbj #ifdef RCONS_16BPP
5249d326d48Sdbj static u_int32_t twobytemask[2] = { 0xffff0000, 0x0000ffff };
5259d326d48Sdbj #endif /* RCONS_16BPP */
526a8e925d3Spk #else /*MSBYTE_FIRST*/
527540ab1b8Scgd static u_int32_t bytemask[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
52823795512Sdrochner #ifdef RCONS_2BPP
52923795512Sdrochner static u_int32_t twobitmask[16] = {
53023795512Sdrochner 0x00000003, 0x0000000c, 0x00000030, 0x000000c0,
53123795512Sdrochner 0x00000300, 0x00000c00, 0x00003000, 0x0000c000,
53223795512Sdrochner 0x00030000, 0x000c0000, 0x00300000, 0x00c00000,
53323795512Sdrochner 0x03000000, 0x0c000000, 0x30000000, 0xc0000000 };
53423795512Sdrochner #endif /* RCONS_2BPP */
535d617933eSscottr #ifdef RCONS_4BPP
536d617933eSscottr static u_int32_t fourbitmask[16] = {
537d617933eSscottr 0x0000000f, 0x000000f0,
538d617933eSscottr 0x00000f00, 0x0000f000,
539d617933eSscottr 0x000f0000, 0x00f00000,
540d617933eSscottr 0x0f000000, 0xf0000000 };
541d617933eSscottr #endif /* RCONS_4BPP */
5429d326d48Sdbj #ifdef RCONS_16BPP
5439d326d48Sdbj static u_int32_t twobytemask[2] = { 0x0000ffff, 0xffff0000 };
5449d326d48Sdbj #endif /* RCONS_16BPP */
545a8e925d3Spk #endif /*MSBYTE_FIRST*/
546a8e925d3Spk
547a8e925d3Spk
548a8e925d3Spk /* Forward routines. */
549a8e925d3Spk
55018db93c7Sperry static int raster_blit(struct raster *, u_int32_t *, int, int, int,
551357fb0e4Schristos struct raster *, u_int32_t *, int, int, int,
55218db93c7Sperry int, int);
553a8e925d3Spk
554a8e925d3Spk /* Raster operations. */
555a8e925d3Spk
556a8e925d3Spk /* Performs a bitblit. Returns 0 on success, -1 on failure. */
557a8e925d3Spk int
raster_op(struct raster * dst,int dx,int dy,int w,int h,int rop,struct raster * src,int sx,int sy)558*91d94812Smatt raster_op(struct raster* dst, int dx, int dy, int w, int h, int rop,
559*91d94812Smatt struct raster* src, int sx, int sy)
560a8e925d3Spk {
561a8e925d3Spk if ( dst == (struct raster*) 0 )
562a8e925d3Spk return -1; /* no destination */
563a8e925d3Spk
564a8e925d3Spk if ( needsrc[RAS_GETOP( rop )] )
565a8e925d3Spk {
566a8e925d3Spk /* Two-operand blit. */
567a8e925d3Spk if ( src == (struct raster*) 0 )
568a8e925d3Spk return -1; /* no source */
569a8e925d3Spk
570a8e925d3Spk /* Clip against source. */
571a8e925d3Spk if ( sx < 0 )
572a8e925d3Spk {
573a8e925d3Spk w += sx;
574a8e925d3Spk sx = 0;
575a8e925d3Spk }
576a8e925d3Spk if ( sy < 0 )
577a8e925d3Spk {
578a8e925d3Spk h += sy;
579a8e925d3Spk sy = 0;
580a8e925d3Spk }
581a8e925d3Spk if ( sx + w > src->width )
582a8e925d3Spk w = src->width - sx;
583a8e925d3Spk if ( sy + h > src->height )
584a8e925d3Spk h = src->height - sy;
585a8e925d3Spk
586a8e925d3Spk /* Clip against dest. */
587a8e925d3Spk if ( dx < 0 )
588a8e925d3Spk {
589a8e925d3Spk w += dx;
590a8e925d3Spk sx -= dx;
591a8e925d3Spk dx = 0;
592a8e925d3Spk }
593a8e925d3Spk if ( dy < 0 )
594a8e925d3Spk {
595a8e925d3Spk h += dy;
596a8e925d3Spk sy -= dy;
597a8e925d3Spk dy = 0;
598a8e925d3Spk }
599a8e925d3Spk if ( dx + w > dst->width )
600a8e925d3Spk w = dst->width - dx;
601a8e925d3Spk if ( dy + h > dst->height )
602a8e925d3Spk h = dst->height - dy;
603a8e925d3Spk
604a8e925d3Spk if ( w <= 0 || h <= 0 )
605a8e925d3Spk return 0; /* nothing to do */
606a8e925d3Spk
607a8e925d3Spk return raster_op_noclip( dst, dx, dy, w, h, rop, src, sx, sy );
608a8e925d3Spk }
609a8e925d3Spk
610a8e925d3Spk /* No source necessary - one-operand blit. */
611a8e925d3Spk if ( src != (struct raster*) 0 )
612a8e925d3Spk return -1; /* unwanted source */
613a8e925d3Spk
614a8e925d3Spk /* Clip against dest. */
615a8e925d3Spk if ( dx < 0 )
616a8e925d3Spk {
617a8e925d3Spk w += dx;
618a8e925d3Spk dx = 0;
619a8e925d3Spk }
620a8e925d3Spk if ( dy < 0 )
621a8e925d3Spk {
622a8e925d3Spk h += dy;
623a8e925d3Spk dy = 0;
624a8e925d3Spk }
625a8e925d3Spk if ( dx + w > dst->width )
626a8e925d3Spk w = dst->width - dx;
627a8e925d3Spk if ( dy + h > dst->height )
628a8e925d3Spk h = dst->height - dy;
629a8e925d3Spk
630a8e925d3Spk if ( w <= 0 || h <= 0 )
631a8e925d3Spk return 0; /* nothing to do */
632a8e925d3Spk
633a8e925d3Spk return raster_op_nosrc_noclip( dst, dx, dy, w, h, rop );
634a8e925d3Spk }
635a8e925d3Spk
636a8e925d3Spk /* Semi-public routine to do a bitblit without clipping. Returns 0 on
637a8e925d3Spk ** success, -1 on failure.
638a8e925d3Spk */
639a8e925d3Spk int
raster_op_noclip(struct raster * dst,int dx,int dy,int w,int h,int rop,struct raster * src,int sx,int sy)640*91d94812Smatt raster_op_noclip(struct raster* dst, int dx, int dy, int w, int h, int rop,
641*91d94812Smatt struct raster* src, int sx, int sy)
642a8e925d3Spk {
643a8e925d3Spk int op;
644a8e925d3Spk
645a8e925d3Spk op = RAS_GETOP( rop );
646a8e925d3Spk
647a8e925d3Spk if ( src->depth == 1 )
648a8e925d3Spk {
649a8e925d3Spk /* One-bit to ? blit. */
650a8e925d3Spk if ( dst->depth == 1 )
651a8e925d3Spk {
652a8e925d3Spk /* One to one blit. */
653540ab1b8Scgd u_int32_t* srclin1;
654540ab1b8Scgd u_int32_t* dstlin1;
655a8e925d3Spk int srcleftignore, srcrightignore, srclongs;
656a8e925d3Spk int dstleftignore, dstrightignore, dstlongs;
657a8e925d3Spk
658a8e925d3Spk srclin1 = RAS_ADDR( src, sx, sy );
659a8e925d3Spk dstlin1 = RAS_ADDR( dst, dx, dy );
660a8e925d3Spk
661a8e925d3Spk #ifdef BCOPY_FASTER
662a8e925d3Spk /* Special-case full-width to full-width copies. */
663a8e925d3Spk if ( op == RAS_SRC && src->width == w && dst->width == w &&
664a8e925d3Spk src->linelongs == dst->linelongs && src->linelongs == w >> 5 )
665a8e925d3Spk {
666a8e925d3Spk bcopy(
667a8e925d3Spk (char*) srclin1, (char*) dstlin1,
668540ab1b8Scgd h * src->linelongs * sizeof(u_int32_t) );
669a8e925d3Spk return 0;
670a8e925d3Spk }
671a8e925d3Spk #endif /*BCOPY_FASTER*/
672a8e925d3Spk
673a8e925d3Spk srcleftignore = ( sx & 31 );
674a8e925d3Spk srclongs = ( srcleftignore + w + 31 ) >> 5;
675a8e925d3Spk srcrightignore = ( srclongs * 32 - w - srcleftignore ) & 31;
676a8e925d3Spk dstleftignore = ( dx & 31 );
677a8e925d3Spk dstlongs = ( dstleftignore + w + 31 ) >> 5;
678a8e925d3Spk dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
679a8e925d3Spk
680a8e925d3Spk return raster_blit(
681a8e925d3Spk src, srclin1, srcleftignore, srcrightignore, srclongs,
682a8e925d3Spk dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
683a8e925d3Spk }
684a8e925d3Spk
68523795512Sdrochner #ifdef RCONS_2BPP
68623795512Sdrochner else if ( dst->depth == 2 )
68723795512Sdrochner {
68823795512Sdrochner /* One to two, using the color in the rop. */
68923795512Sdrochner u_int32_t* srclin1;
69023795512Sdrochner u_int32_t* dstlin1;
69123795512Sdrochner u_int32_t* srclin2;
69223795512Sdrochner u_int32_t* srclin;
69323795512Sdrochner u_int32_t* dstlin;
694169ac5b3Saugustss u_int32_t* srclong;
695169ac5b3Saugustss u_int32_t* dstlong;
696169ac5b3Saugustss u_int32_t color, dl;
697169ac5b3Saugustss int srcbit, dstbyte, i;
69823795512Sdrochner
69923795512Sdrochner color = RAS_GETCOLOR( rop );
70023795512Sdrochner if ( color == 0 )
70123795512Sdrochner color = 3;
70223795512Sdrochner
70323795512Sdrochner /* Make 32 bits of color so we can do the ROP without shifting. */
70423795512Sdrochner color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
70523795512Sdrochner | ( color << 24 ) | ( color << 22 ) | ( color << 20 )
70623795512Sdrochner | ( color << 18 ) | ( color << 16 ) | ( color << 14 )
70723795512Sdrochner | ( color << 12 ) | ( color << 10 ) | ( color << 8 )
70823795512Sdrochner | ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
70923795512Sdrochner
71023795512Sdrochner /* Don't have to worry about overlapping blits here. */
71123795512Sdrochner srclin1 = RAS_ADDR( src, sx, sy );
71223795512Sdrochner srclin2 = srclin1 + h * src->linelongs;
71323795512Sdrochner dstlin1 = RAS_ADDR( dst, dx, dy );
71423795512Sdrochner srclin = srclin1;
71523795512Sdrochner dstlin = dstlin1;
71623795512Sdrochner
71723795512Sdrochner while ( srclin != srclin2 )
71823795512Sdrochner {
71923795512Sdrochner srclong = srclin;
72023795512Sdrochner srcbit = sx & 31;
72123795512Sdrochner dstlong = dstlin;
72223795512Sdrochner dstbyte = dx & 15;
72323795512Sdrochner i = w;
72423795512Sdrochner
72523795512Sdrochner /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
72623795512Sdrochner ROP_SRCDSTCOLOR(
72723795512Sdrochner /*op*/ op,
72823795512Sdrochner /*pre*/ while ( i > 0 )
72923795512Sdrochner {
73023795512Sdrochner dl = *dstlong;,
73123795512Sdrochner /*s*/ *srclong & raster_bitmask[srcbit],
73223795512Sdrochner /*d*/ dl,
73323795512Sdrochner /*c*/ color,
73423795512Sdrochner /*pst*/ *dstlong = ( *dstlong & ~twobitmask[dstbyte] ) |
73523795512Sdrochner ( dl & twobitmask[dstbyte] );
73623795512Sdrochner if ( srcbit == 31 )
73723795512Sdrochner {
73823795512Sdrochner srcbit = 0;
73923795512Sdrochner ++srclong;
74023795512Sdrochner }
74123795512Sdrochner else
74223795512Sdrochner ++srcbit;
74323795512Sdrochner if ( dstbyte == 15 )
74423795512Sdrochner {
74523795512Sdrochner dstbyte = 0;
74623795512Sdrochner ++dstlong;
74723795512Sdrochner }
74823795512Sdrochner else
74923795512Sdrochner ++dstbyte;
75023795512Sdrochner --i;
75123795512Sdrochner } )
75223795512Sdrochner
75323795512Sdrochner srclin += src->linelongs;
75423795512Sdrochner dstlin += dst->linelongs;
75523795512Sdrochner }
75623795512Sdrochner }
75723795512Sdrochner #endif /* RCONS_2BPP */
758d617933eSscottr #ifdef RCONS_4BPP
759d617933eSscottr else if ( dst->depth == 4 )
760d617933eSscottr {
761d617933eSscottr /* One to four, using the color in the rop. */
762d617933eSscottr u_int32_t* srclin1;
763d617933eSscottr u_int32_t* dstlin1;
764d617933eSscottr u_int32_t* srclin2;
765d617933eSscottr u_int32_t* srclin;
766d617933eSscottr u_int32_t* dstlin;
767169ac5b3Saugustss u_int32_t* srclong;
768169ac5b3Saugustss u_int32_t* dstlong;
769169ac5b3Saugustss u_int32_t color, dl;
770169ac5b3Saugustss int srcbit, dstbyte, i;
771d617933eSscottr
772d617933eSscottr color = RAS_GETCOLOR( rop );
773d617933eSscottr if ( color == 0 )
774d617933eSscottr color = 15;
775d617933eSscottr
776d617933eSscottr /* Make 32 bits of color so we can do the ROP without shifting. */
777d617933eSscottr color |= (( color << 28 ) | ( color << 24 )
778d617933eSscottr | ( color << 20 ) | ( color << 16 )
779d617933eSscottr | ( color << 12 ) | ( color << 8 )
780d617933eSscottr | ( color << 4 ));
781d617933eSscottr
782d617933eSscottr /* Don't have to worry about overlapping blits here. */
783d617933eSscottr srclin1 = RAS_ADDR( src, sx, sy );
784d617933eSscottr srclin2 = srclin1 + h * src->linelongs;
785d617933eSscottr dstlin1 = RAS_ADDR( dst, dx, dy );
786d617933eSscottr srclin = srclin1;
787d617933eSscottr dstlin = dstlin1;
788d617933eSscottr
789d617933eSscottr while ( srclin != srclin2 )
790d617933eSscottr {
791d617933eSscottr srclong = srclin;
792d617933eSscottr srcbit = sx & 31;
793d617933eSscottr dstlong = dstlin;
794d617933eSscottr dstbyte = dx & 7;
795d617933eSscottr i = w;
796d617933eSscottr
797d617933eSscottr /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
798d617933eSscottr ROP_SRCDSTCOLOR(
799d617933eSscottr /*op*/ op,
800d617933eSscottr /*pre*/ while ( i > 0 )
801d617933eSscottr {
802d617933eSscottr dl = *dstlong;,
803d617933eSscottr /*s*/ *srclong & raster_bitmask[srcbit],
804d617933eSscottr /*d*/ dl,
805d617933eSscottr /*c*/ color,
806d617933eSscottr /*pst*/ *dstlong = ( *dstlong & ~fourbitmask[dstbyte] ) |
807d617933eSscottr ( dl & fourbitmask[dstbyte] );
808d617933eSscottr if ( srcbit == 31 )
809d617933eSscottr {
810d617933eSscottr srcbit = 0;
811d617933eSscottr ++srclong;
812d617933eSscottr }
813d617933eSscottr else
814d617933eSscottr ++srcbit;
815d617933eSscottr if ( dstbyte == 7 )
816d617933eSscottr {
817d617933eSscottr dstbyte = 0;
818d617933eSscottr ++dstlong;
819d617933eSscottr }
820d617933eSscottr else
821d617933eSscottr ++dstbyte;
822d617933eSscottr --i;
823d617933eSscottr } )
824d617933eSscottr
825d617933eSscottr srclin += src->linelongs;
826d617933eSscottr dstlin += dst->linelongs;
827d617933eSscottr }
828d617933eSscottr }
829d617933eSscottr #endif /* RCONS_4BPP */
8309d326d48Sdbj else if ( dst->depth == 8 )
831a8e925d3Spk {
832a8e925d3Spk /* One to eight, using the color in the rop. This could
833a8e925d3Spk ** probably be sped up by handling each four-bit source nybble
834a8e925d3Spk ** as a group, indexing into a 16-element runtime-constructed
835a8e925d3Spk ** table of longwords.
836a8e925d3Spk */
837540ab1b8Scgd u_int32_t* srclin1;
838540ab1b8Scgd u_int32_t* dstlin1;
839540ab1b8Scgd u_int32_t* srclin2;
840540ab1b8Scgd u_int32_t* srclin;
841540ab1b8Scgd u_int32_t* dstlin;
842169ac5b3Saugustss u_int32_t* srclong;
843169ac5b3Saugustss u_int32_t* dstlong;
844169ac5b3Saugustss u_int32_t color, dl;
845169ac5b3Saugustss int srcbit, dstbyte, i;
846a8e925d3Spk
847a8e925d3Spk color = RAS_GETCOLOR( rop );
848a8e925d3Spk if ( color == 0 )
849a8e925d3Spk color = 255;
850a8e925d3Spk
851a8e925d3Spk /* Make 32 bits of color so we can do the ROP without shifting. */
852a8e925d3Spk color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
853a8e925d3Spk
854a8e925d3Spk /* Don't have to worry about overlapping blits here. */
855a8e925d3Spk srclin1 = RAS_ADDR( src, sx, sy );
856a8e925d3Spk srclin2 = srclin1 + h * src->linelongs;
857a8e925d3Spk dstlin1 = RAS_ADDR( dst, dx, dy );
858a8e925d3Spk srclin = srclin1;
859a8e925d3Spk dstlin = dstlin1;
860a8e925d3Spk while ( srclin != srclin2 )
861a8e925d3Spk {
862a8e925d3Spk srclong = srclin;
863a8e925d3Spk srcbit = sx & 31;
864a8e925d3Spk dstlong = dstlin;
865a8e925d3Spk dstbyte = dx & 3;
866a8e925d3Spk i = w;
867a8e925d3Spk
868a8e925d3Spk /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
869a8e925d3Spk ROP_SRCDSTCOLOR(
870a8e925d3Spk /*op*/ op,
871a8e925d3Spk /*pre*/ while ( i > 0 )
872a8e925d3Spk {
873a8e925d3Spk dl = *dstlong;,
874a8e925d3Spk /*s*/ *srclong & raster_bitmask[srcbit],
875a8e925d3Spk /*d*/ dl,
876a8e925d3Spk /*c*/ color,
877a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & ~bytemask[dstbyte] ) |
878a8e925d3Spk ( dl & bytemask[dstbyte] );
879a8e925d3Spk if ( srcbit == 31 )
880a8e925d3Spk {
881a8e925d3Spk srcbit = 0;
882a8e925d3Spk ++srclong;
883a8e925d3Spk }
884a8e925d3Spk else
885a8e925d3Spk ++srcbit;
886a8e925d3Spk if ( dstbyte == 3 )
887a8e925d3Spk {
888a8e925d3Spk dstbyte = 0;
889a8e925d3Spk ++dstlong;
890a8e925d3Spk }
891a8e925d3Spk else
892a8e925d3Spk ++dstbyte;
893a8e925d3Spk --i;
894a8e925d3Spk } )
895a8e925d3Spk
896a8e925d3Spk srclin += src->linelongs;
897a8e925d3Spk dstlin += dst->linelongs;
898a8e925d3Spk }
899a8e925d3Spk }
9009d326d48Sdbj #ifdef RCONS_16BPP
9019d326d48Sdbj else
9029d326d48Sdbj {
9039d326d48Sdbj /* One to sixteen, using the color in the rop. This could
9049d326d48Sdbj ** probably be sped up by handling each four-bit source nybble
9059d326d48Sdbj ** as a group, indexing into a 16-element runtime-constructed
9069d326d48Sdbj ** table of longwords.
9079d326d48Sdbj */
9089d326d48Sdbj u_int32_t* srclin1;
9099d326d48Sdbj u_int32_t* dstlin1;
9109d326d48Sdbj u_int32_t* srclin2;
9119d326d48Sdbj u_int32_t* srclin;
9129d326d48Sdbj u_int32_t* dstlin;
913169ac5b3Saugustss u_int32_t* srclong;
914169ac5b3Saugustss u_int32_t* dstlong;
915169ac5b3Saugustss u_int32_t color, dl;
916169ac5b3Saugustss int srcbit, dstbyte, i;
9179d326d48Sdbj
9189d326d48Sdbj color = RAS_GETCOLOR( rop );
9199d326d48Sdbj if ( color == 0 )
9209a37177dSdeberg color = 0xffff;
9219d326d48Sdbj
9229d326d48Sdbj /* Make 32 bits of color so we can do the ROP without shifting. */
9239d326d48Sdbj color |= ( color << 16 );
9249d326d48Sdbj
9259d326d48Sdbj /* Don't have to worry about overlapping blits here. */
9269d326d48Sdbj srclin1 = RAS_ADDR( src, sx, sy );
9279d326d48Sdbj srclin2 = srclin1 + h * src->linelongs;
9289d326d48Sdbj dstlin1 = RAS_ADDR( dst, dx, dy );
9299d326d48Sdbj srclin = srclin1;
9309d326d48Sdbj dstlin = dstlin1;
9319d326d48Sdbj while ( srclin != srclin2 )
9329d326d48Sdbj {
9339d326d48Sdbj srclong = srclin;
9349d326d48Sdbj srcbit = sx & 31;
9359d326d48Sdbj dstlong = dstlin;
9369d326d48Sdbj dstbyte = dx & 1;
9379d326d48Sdbj i = w;
9389d326d48Sdbj
9399d326d48Sdbj /* WARNING: this code is KNOWN TO FAIL on Sun 3's / CG2's. */
9409d326d48Sdbj ROP_SRCDSTCOLOR(
9419d326d48Sdbj /*op*/ op,
9429d326d48Sdbj /*pre*/ while ( i > 0 )
9439d326d48Sdbj {
9449d326d48Sdbj dl = *dstlong;,
9459d326d48Sdbj /*s*/ *srclong & raster_bitmask[srcbit],
9469d326d48Sdbj /*d*/ dl,
9479d326d48Sdbj /*c*/ color,
9489d326d48Sdbj /*pst*/ *dstlong = ( *dstlong & ~twobytemask[dstbyte] ) |
9499d326d48Sdbj ( dl & twobytemask[dstbyte] );
9509d326d48Sdbj if ( srcbit == 31 )
9519d326d48Sdbj {
9529d326d48Sdbj srcbit = 0;
9539d326d48Sdbj ++srclong;
9549d326d48Sdbj }
9559d326d48Sdbj else
9569d326d48Sdbj ++srcbit;
9579d326d48Sdbj if ( dstbyte == 1 )
9589d326d48Sdbj {
9599d326d48Sdbj dstbyte = 0;
9609d326d48Sdbj ++dstlong;
9619d326d48Sdbj }
9629d326d48Sdbj else
9639d326d48Sdbj ++dstbyte;
9649d326d48Sdbj --i;
9659d326d48Sdbj } )
9669d326d48Sdbj
9679d326d48Sdbj srclin += src->linelongs;
9689d326d48Sdbj dstlin += dst->linelongs;
9699d326d48Sdbj }
9709d326d48Sdbj }
9719d326d48Sdbj #endif /* RCONS_16BPP */
972a8e925d3Spk }
97323795512Sdrochner #ifdef RCONS_2BPP
97423795512Sdrochner else if ( src->depth == 2 )
97523795512Sdrochner {
97623795512Sdrochner /* Two to two blit. */
97723795512Sdrochner u_int32_t* srclin1;
97823795512Sdrochner u_int32_t* dstlin1;
97923795512Sdrochner int srcleftignore, srcrightignore, srclongs;
98023795512Sdrochner int dstleftignore, dstrightignore, dstlongs;
98123795512Sdrochner
98223795512Sdrochner srclin1 = RAS_ADDR( src, sx, sy );
98323795512Sdrochner dstlin1 = RAS_ADDR( dst, dx, dy );
98423795512Sdrochner
98523795512Sdrochner srcleftignore = ( sx & 15 ) * 2;
98623795512Sdrochner srclongs = ( srcleftignore + w * 2 + 31 ) >> 5;
98723795512Sdrochner srcrightignore = ( srclongs * 32 - w * 2 - srcleftignore ) & 31;
98823795512Sdrochner dstleftignore = ( dx & 15 ) * 2;
98923795512Sdrochner dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
99023795512Sdrochner dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
99123795512Sdrochner
99223795512Sdrochner return raster_blit(
99323795512Sdrochner src, srclin1, srcleftignore, srcrightignore, srclongs,
99423795512Sdrochner dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
99523795512Sdrochner }
99623795512Sdrochner #endif /* RCONS_2BPP */
997d617933eSscottr #ifdef RCONS_4BPP
998d617933eSscottr else if ( src->depth == 4 )
999d617933eSscottr {
1000d617933eSscottr /* Four to four blit. */
1001d617933eSscottr u_int32_t* srclin1;
1002d617933eSscottr u_int32_t* dstlin1;
1003d617933eSscottr int srcleftignore, srcrightignore, srclongs;
1004d617933eSscottr int dstleftignore, dstrightignore, dstlongs;
1005d617933eSscottr
1006d617933eSscottr srclin1 = RAS_ADDR( src, sx, sy );
1007d617933eSscottr dstlin1 = RAS_ADDR( dst, dx, dy );
1008d617933eSscottr
1009d617933eSscottr srcleftignore = ( sx & 7 ) * 4;
1010d617933eSscottr srclongs = ( srcleftignore + w * 4 + 31 ) >> 5;
1011d617933eSscottr srcrightignore = ( srclongs * 32 - w * 4 - srcleftignore ) & 31;
1012d617933eSscottr dstleftignore = ( dx & 7 ) * 4;
1013d617933eSscottr dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5;
1014d617933eSscottr dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31;
1015d617933eSscottr
1016d617933eSscottr return raster_blit(
1017d617933eSscottr src, srclin1, srcleftignore, srcrightignore, srclongs,
1018d617933eSscottr dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1019d617933eSscottr }
1020d617933eSscottr #endif /* RCONS_4BPP */
1021a8e925d3Spk
10229d326d48Sdbj else if ( src->depth == 8 )
1023a8e925d3Spk {
1024a8e925d3Spk /* Eight to eight blit. */
1025540ab1b8Scgd u_int32_t* srclin1;
1026540ab1b8Scgd u_int32_t* dstlin1;
1027a8e925d3Spk int srcleftignore, srcrightignore, srclongs;
1028a8e925d3Spk int dstleftignore, dstrightignore, dstlongs;
1029a8e925d3Spk
1030a8e925d3Spk if ( dst->depth != 8 )
1031a8e925d3Spk return -1; /* depth mismatch */
1032a8e925d3Spk
1033a8e925d3Spk srclin1 = RAS_ADDR( src, sx, sy );
1034a8e925d3Spk dstlin1 = RAS_ADDR( dst, dx, dy );
1035a8e925d3Spk
1036a8e925d3Spk #ifdef BCOPY_FASTER
1037a8e925d3Spk /* Special-case full-width to full-width copies. */
1038a8e925d3Spk if ( op == RAS_SRC && src->width == w && dst->width == w &&
1039a8e925d3Spk src->linelongs == dst->linelongs && src->linelongs == w >> 2 )
1040a8e925d3Spk {
1041d24f7d61Stsutsui bcopy( (char*) srclin1, (char*) dstlin1,
1042540ab1b8Scgd h * src->linelongs * sizeof(u_int32_t) );
1043a8e925d3Spk return 0;
1044a8e925d3Spk }
1045a8e925d3Spk #endif /*BCOPY_FASTER*/
1046a8e925d3Spk
1047a8e925d3Spk srcleftignore = ( sx & 3 ) * 8;
1048a8e925d3Spk srclongs = ( srcleftignore + w * 8 + 31 ) >> 5;
1049a8e925d3Spk srcrightignore = ( srclongs * 32 - w * 8 - srcleftignore ) & 31;
1050a8e925d3Spk dstleftignore = ( dx & 3 ) * 8;
1051a8e925d3Spk dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
1052a8e925d3Spk dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
1053a8e925d3Spk
1054a8e925d3Spk return raster_blit(
1055a8e925d3Spk src, srclin1, srcleftignore, srcrightignore, srclongs,
1056a8e925d3Spk dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
1057a8e925d3Spk }
10589d326d48Sdbj #ifdef RCONS_16BPP
10599d326d48Sdbj else
10609d326d48Sdbj {
10619d326d48Sdbj /* Sixteen to sixteen blit. */
10629d326d48Sdbj u_int32_t* srclin1;
10639d326d48Sdbj u_int32_t* dstlin1;
10649d326d48Sdbj int srcleftignore, srcrightignore, srclongs;
10659d326d48Sdbj int dstleftignore, dstrightignore, dstlongs;
1066a8e925d3Spk
10679d326d48Sdbj srclin1 = RAS_ADDR( src, sx, sy );
10689d326d48Sdbj dstlin1 = RAS_ADDR( dst, dx, dy );
10699d326d48Sdbj
10709d326d48Sdbj srcleftignore = ( sx & 1 ) * 16;
10719d326d48Sdbj srclongs = ( srcleftignore + w * 16 + 31 ) >> 5;
10729d326d48Sdbj srcrightignore = ( srclongs * 32 - w * 16 - srcleftignore ) & 31;
10739d326d48Sdbj dstleftignore = ( dx & 1 ) * 16;
10749d326d48Sdbj dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5;
10759d326d48Sdbj dstrightignore = ( dstlongs * 32 - w * 16 - dstleftignore ) & 31;
10769d326d48Sdbj
10779d326d48Sdbj return raster_blit(
10789d326d48Sdbj src, srclin1, srcleftignore, srcrightignore, srclongs,
10799d326d48Sdbj dst, dstlin1, dstleftignore, dstrightignore, dstlongs, h, op );
10809d326d48Sdbj }
10819d326d48Sdbj #endif /* RCONS_16BPP */
1082a8e925d3Spk return 0;
1083a8e925d3Spk }
1084a8e925d3Spk
1085a8e925d3Spk /* Semi-public routine to do a no-src bitblit without clipping. Returns 0
1086a8e925d3Spk ** on success, -1 on failure.
1087a8e925d3Spk */
1088a8e925d3Spk int
raster_op_nosrc_noclip(struct raster * dst,int dx,int dy,int w,int h,int rop)1089*91d94812Smatt raster_op_nosrc_noclip(struct raster* dst,
1090*91d94812Smatt int dx, int dy, int w, int h, int rop)
1091a8e925d3Spk {
1092a8e925d3Spk int op;
1093a8e925d3Spk
1094a8e925d3Spk op = RAS_GETOP( rop );
1095a8e925d3Spk
1096a8e925d3Spk if ( dst->depth == 1 )
1097a8e925d3Spk {
1098a8e925d3Spk /* One-bit no-src blit. */
1099540ab1b8Scgd u_int32_t* dstlin1;
1100540ab1b8Scgd u_int32_t* dstlin2;
1101540ab1b8Scgd u_int32_t* dstlin;
1102a8e925d3Spk int dstleftignore, dstrightignore, dstlongs;
1103540ab1b8Scgd u_int32_t dl, lm, nlm, rm, nrm;
1104169ac5b3Saugustss u_int32_t* dstlong2;
1105169ac5b3Saugustss u_int32_t* dstlong;
1106a8e925d3Spk
1107a8e925d3Spk dstlin1 = RAS_ADDR( dst, dx, dy );
1108a8e925d3Spk
1109a8e925d3Spk #ifdef BCOPY_FASTER
1110a8e925d3Spk /* Special-case full-width clears. */
1111a8e925d3Spk if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 5 )
1112a8e925d3Spk {
1113c363a9cbScegger memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1114a8e925d3Spk return 0;
1115a8e925d3Spk }
1116a8e925d3Spk #endif /*BCOPY_FASTER*/
1117a8e925d3Spk
1118a8e925d3Spk dstleftignore = ( dx & 31 );
1119a8e925d3Spk dstlongs = ( dstleftignore + w + 31 ) >> 5;
1120a8e925d3Spk dstrightignore = ( dstlongs * 32 - w - dstleftignore ) & 31;
1121a8e925d3Spk
1122a8e925d3Spk dstlin2 = dstlin1 + h * dst->linelongs;
1123a8e925d3Spk dstlin = dstlin1;
1124a8e925d3Spk
1125a8e925d3Spk if ( dstlongs == 1 )
1126a8e925d3Spk {
1127a8e925d3Spk /* It fits into a single longword. */
1128a8e925d3Spk lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1129a8e925d3Spk nlm = ~lm;
1130a8e925d3Spk while ( dstlin != dstlin2 )
1131a8e925d3Spk {
1132a8e925d3Spk ROP_DST(
1133a8e925d3Spk /*op*/ op,
1134a8e925d3Spk /*pre*/ dl = *dstlin;,
1135a8e925d3Spk /*d*/ dl,
1136a8e925d3Spk /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1137a8e925d3Spk
1138a8e925d3Spk dstlin += dst->linelongs;
1139a8e925d3Spk }
1140a8e925d3Spk }
1141a8e925d3Spk else
1142a8e925d3Spk {
1143a8e925d3Spk lm = leftmask[dstleftignore];
1144a8e925d3Spk rm = rightmask[dstrightignore];
1145a8e925d3Spk nrm = ~rm;
1146a8e925d3Spk nlm = ~lm;
1147a8e925d3Spk
1148a8e925d3Spk while ( dstlin != dstlin2 )
1149a8e925d3Spk {
1150a8e925d3Spk dstlong = dstlin;
1151a8e925d3Spk dstlong2 = dstlong + dstlongs;
1152a8e925d3Spk if ( dstrightignore != 0 )
1153a8e925d3Spk --dstlong2;
1154a8e925d3Spk
1155a8e925d3Spk /* Leading edge. */
1156a8e925d3Spk if ( dstleftignore != 0 )
1157a8e925d3Spk {
1158a8e925d3Spk ROP_DST(
1159a8e925d3Spk /*op*/ op,
1160a8e925d3Spk /*pre*/ dl = *dstlong;,
1161a8e925d3Spk /*d*/ dl,
1162a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1163a8e925d3Spk ++dstlong;
1164a8e925d3Spk }
1165a8e925d3Spk
1166a8e925d3Spk /* Main rop. */
1167a8e925d3Spk ROP_DST(
1168a8e925d3Spk /*op*/ op,
1169a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1170a8e925d3Spk {,
1171a8e925d3Spk /*d*/ *dstlong,
1172a8e925d3Spk /*pst*/ ++dstlong;
1173a8e925d3Spk } )
1174a8e925d3Spk
1175a8e925d3Spk /* Trailing edge. */
1176a8e925d3Spk if ( dstrightignore != 0 )
1177a8e925d3Spk {
1178a8e925d3Spk ROP_DST(
1179a8e925d3Spk /*op*/ op,
1180a8e925d3Spk /*pre*/ dl = *dstlong;,
1181a8e925d3Spk /*d*/ dl,
1182a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1183a8e925d3Spk }
1184a8e925d3Spk
1185a8e925d3Spk dstlin += dst->linelongs;
1186a8e925d3Spk }
1187a8e925d3Spk }
1188a8e925d3Spk }
1189a8e925d3Spk
119023795512Sdrochner #ifdef RCONS_2BPP
119123795512Sdrochner else if ( dst->depth == 2 )
119223795512Sdrochner {
119323795512Sdrochner /* Two-bit no-src blit. */
1194169ac5b3Saugustss u_int32_t color;
119523795512Sdrochner u_int32_t* dstlin1;
119623795512Sdrochner u_int32_t* dstlin2;
119723795512Sdrochner u_int32_t* dstlin;
119823795512Sdrochner int dstleftignore, dstrightignore, dstlongs;
119923795512Sdrochner u_int32_t dl, lm, nlm, rm, nrm;
1200169ac5b3Saugustss u_int32_t* dstlong2;
1201169ac5b3Saugustss u_int32_t* dstlong;
120223795512Sdrochner
120323795512Sdrochner dstlin1 = RAS_ADDR( dst, dx, dy );
120423795512Sdrochner
120523795512Sdrochner #ifdef BCOPY_FASTER
120623795512Sdrochner /* Special-case full-width clears. */
12079d326d48Sdbj if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 4 )
120823795512Sdrochner {
1209c363a9cbScegger memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
121023795512Sdrochner return 0;
121123795512Sdrochner }
121223795512Sdrochner #endif /*BCOPY_FASTER*/
121323795512Sdrochner
121423795512Sdrochner color = RAS_GETCOLOR( rop );
121523795512Sdrochner if ( color == 0 )
121623795512Sdrochner color = 3;
121723795512Sdrochner
121823795512Sdrochner /* Make 32 bits of color so we can do the ROP without shifting. */
121923795512Sdrochner color |= (( color << 30 ) | ( color << 28 ) | ( color << 26 )
122023795512Sdrochner | ( color << 24 ) | ( color << 22 ) | ( color << 20 )
122123795512Sdrochner | ( color << 18 ) | ( color << 16 ) | ( color << 14 )
122223795512Sdrochner | ( color << 12 ) | ( color << 10 ) | ( color << 8 )
122323795512Sdrochner | ( color << 6 ) | ( color << 4 ) | ( color << 2 ));
122423795512Sdrochner
122523795512Sdrochner dstleftignore = ( dx & 15 ) * 2;
122623795512Sdrochner dstlongs = ( dstleftignore + w * 2 + 31 ) >> 5;
122723795512Sdrochner dstrightignore = ( dstlongs * 32 - w * 2 - dstleftignore ) & 31;
122823795512Sdrochner
122923795512Sdrochner dstlin2 = dstlin1 + h * dst->linelongs;
123023795512Sdrochner dstlin = dstlin1;
123123795512Sdrochner
123223795512Sdrochner if ( dstlongs == 1 )
123323795512Sdrochner {
123423795512Sdrochner /* It fits into a single longword. */
123523795512Sdrochner lm = leftmask[dstleftignore] | rightmask[dstrightignore];
123623795512Sdrochner nlm = ~lm;
123723795512Sdrochner while ( dstlin != dstlin2 )
123823795512Sdrochner {
123923795512Sdrochner ROP_DST(
124023795512Sdrochner /*op*/ op,
124123795512Sdrochner /*pre*/ dl = *dstlin;,
124223795512Sdrochner /*d*/ dl,
124323795512Sdrochner /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
124423795512Sdrochner
124523795512Sdrochner dstlin += dst->linelongs;
124623795512Sdrochner }
124723795512Sdrochner }
124823795512Sdrochner else
124923795512Sdrochner {
125023795512Sdrochner lm = leftmask[dstleftignore];
125123795512Sdrochner rm = rightmask[dstrightignore];
125223795512Sdrochner nrm = ~rm;
125323795512Sdrochner nlm = ~lm;
125423795512Sdrochner
125523795512Sdrochner while ( dstlin != dstlin2 )
125623795512Sdrochner {
125723795512Sdrochner dstlong = dstlin;
125823795512Sdrochner dstlong2 = dstlong + dstlongs;
125923795512Sdrochner if ( dstrightignore != 0 )
126023795512Sdrochner --dstlong2;
126123795512Sdrochner
126223795512Sdrochner /* Leading edge. */
126323795512Sdrochner if ( dstleftignore != 0 )
126423795512Sdrochner {
126523795512Sdrochner ROP_DST(
126623795512Sdrochner /*op*/ op,
126723795512Sdrochner /*pre*/ dl = *dstlong;,
126823795512Sdrochner /*d*/ dl,
126923795512Sdrochner /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
127023795512Sdrochner ++dstlong;
127123795512Sdrochner }
127223795512Sdrochner
127323795512Sdrochner /* Main rop. */
127423795512Sdrochner ROP_DST(
127523795512Sdrochner /*op*/ op,
127623795512Sdrochner /*pre*/ while ( dstlong != dstlong2 )
127723795512Sdrochner {,
127823795512Sdrochner /*d*/ *dstlong,
127923795512Sdrochner /*pst*/ ++dstlong;
128023795512Sdrochner } )
128123795512Sdrochner
128223795512Sdrochner /* Trailing edge. */
128323795512Sdrochner if ( dstrightignore != 0 )
128423795512Sdrochner {
128523795512Sdrochner ROP_DST(
128623795512Sdrochner /*op*/ op,
128723795512Sdrochner /*pre*/ dl = *dstlong;,
128823795512Sdrochner /*d*/ dl,
128923795512Sdrochner /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
129023795512Sdrochner }
129123795512Sdrochner
129223795512Sdrochner dstlin += dst->linelongs;
129323795512Sdrochner }
129423795512Sdrochner }
129523795512Sdrochner }
129623795512Sdrochner #endif /* RCONS_2BPP */
1297d617933eSscottr #ifdef RCONS_4BPP
1298d617933eSscottr else if ( dst->depth == 4 )
1299d617933eSscottr {
1300d617933eSscottr /* Two-bit no-src blit. */
1301169ac5b3Saugustss u_int32_t color;
1302d617933eSscottr u_int32_t* dstlin1;
1303d617933eSscottr u_int32_t* dstlin2;
1304d617933eSscottr u_int32_t* dstlin;
1305d617933eSscottr int dstleftignore, dstrightignore, dstlongs;
1306d617933eSscottr u_int32_t dl, lm, nlm, rm, nrm;
1307169ac5b3Saugustss u_int32_t* dstlong2;
1308169ac5b3Saugustss u_int32_t* dstlong;
1309d617933eSscottr
1310d617933eSscottr dstlin1 = RAS_ADDR( dst, dx, dy );
1311d617933eSscottr
1312d617933eSscottr #ifdef BCOPY_FASTER
1313d617933eSscottr /* Special-case full-width clears. */
1314d617933eSscottr if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 3 )
1315d617933eSscottr {
1316c363a9cbScegger memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1317d617933eSscottr return 0;
1318d617933eSscottr }
1319d617933eSscottr #endif /*BCOPY_FASTER*/
1320d617933eSscottr
1321d617933eSscottr color = RAS_GETCOLOR( rop );
1322d617933eSscottr if ( color == 0 )
1323d617933eSscottr color = 15;
1324d617933eSscottr
1325d617933eSscottr /* Make 32 bits of color so we can do the ROP without shifting. */
1326d617933eSscottr color |= (( color << 28 ) | ( color << 24 )
1327d617933eSscottr | ( color << 20 ) | ( color << 16 )
1328d617933eSscottr | ( color << 12 ) | ( color << 8 )
1329d617933eSscottr | ( color << 4 ));
1330d617933eSscottr
1331d617933eSscottr dstleftignore = ( dx & 7 ) * 4;
1332d617933eSscottr dstlongs = ( dstleftignore + w * 4 + 31 ) >> 5;
1333d617933eSscottr dstrightignore = ( dstlongs * 32 - w * 4 - dstleftignore ) & 31;
1334d617933eSscottr
1335d617933eSscottr dstlin2 = dstlin1 + h * dst->linelongs;
1336d617933eSscottr dstlin = dstlin1;
1337d617933eSscottr
1338d617933eSscottr if ( dstlongs == 1 )
1339d617933eSscottr {
1340d617933eSscottr /* It fits into a single longword. */
1341d617933eSscottr lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1342d617933eSscottr nlm = ~lm;
1343d617933eSscottr while ( dstlin != dstlin2 )
1344d617933eSscottr {
1345d617933eSscottr ROP_DST(
1346d617933eSscottr /*op*/ op,
1347d617933eSscottr /*pre*/ dl = *dstlin;,
1348d617933eSscottr /*d*/ dl,
1349d617933eSscottr /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1350d617933eSscottr
1351d617933eSscottr dstlin += dst->linelongs;
1352d617933eSscottr }
1353d617933eSscottr }
1354d617933eSscottr else
1355d617933eSscottr {
1356d617933eSscottr lm = leftmask[dstleftignore];
1357d617933eSscottr rm = rightmask[dstrightignore];
1358d617933eSscottr nrm = ~rm;
1359d617933eSscottr nlm = ~lm;
1360d617933eSscottr
1361d617933eSscottr while ( dstlin != dstlin2 )
1362d617933eSscottr {
1363d617933eSscottr dstlong = dstlin;
1364d617933eSscottr dstlong2 = dstlong + dstlongs;
1365d617933eSscottr if ( dstrightignore != 0 )
1366d617933eSscottr --dstlong2;
1367d617933eSscottr
1368d617933eSscottr /* Leading edge. */
1369d617933eSscottr if ( dstleftignore != 0 )
1370d617933eSscottr {
1371d617933eSscottr ROP_DST(
1372d617933eSscottr /*op*/ op,
1373d617933eSscottr /*pre*/ dl = *dstlong;,
1374d617933eSscottr /*d*/ dl,
1375d617933eSscottr /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1376d617933eSscottr ++dstlong;
1377d617933eSscottr }
1378d617933eSscottr
1379d617933eSscottr /* Main rop. */
1380d617933eSscottr ROP_DST(
1381d617933eSscottr /*op*/ op,
1382d617933eSscottr /*pre*/ while ( dstlong != dstlong2 )
1383d617933eSscottr {,
1384d617933eSscottr /*d*/ *dstlong,
1385d617933eSscottr /*pst*/ ++dstlong;
1386d617933eSscottr } )
1387d617933eSscottr
1388d617933eSscottr /* Trailing edge. */
1389d617933eSscottr if ( dstrightignore != 0 )
1390d617933eSscottr {
1391d617933eSscottr ROP_DST(
1392d617933eSscottr /*op*/ op,
1393d617933eSscottr /*pre*/ dl = *dstlong;,
1394d617933eSscottr /*d*/ dl,
1395d617933eSscottr /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1396d617933eSscottr }
1397d617933eSscottr
1398d617933eSscottr dstlin += dst->linelongs;
1399d617933eSscottr }
1400d617933eSscottr }
1401d617933eSscottr }
1402d617933eSscottr #endif /* RCONS_4BPP */
14039d326d48Sdbj else if ( dst->depth == 8)
1404a8e925d3Spk {
1405a8e925d3Spk /* Eight-bit no-src blit. */
1406169ac5b3Saugustss u_int32_t color;
1407540ab1b8Scgd u_int32_t* dstlin1;
1408540ab1b8Scgd u_int32_t* dstlin2;
1409540ab1b8Scgd u_int32_t* dstlin;
1410a8e925d3Spk int dstleftignore, dstrightignore, dstlongs;
1411540ab1b8Scgd u_int32_t dl, lm, nlm, rm, nrm;
1412169ac5b3Saugustss u_int32_t* dstlong2;
1413169ac5b3Saugustss u_int32_t* dstlong;
1414a8e925d3Spk
1415a8e925d3Spk dstlin1 = RAS_ADDR( dst, dx, dy );
1416a8e925d3Spk
1417a8e925d3Spk #ifdef BCOPY_FASTER
1418a8e925d3Spk /* Special-case full-width clears. */
1419a8e925d3Spk if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 2 )
1420a8e925d3Spk {
1421c363a9cbScegger memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
1422a8e925d3Spk return 0;
1423a8e925d3Spk }
1424a8e925d3Spk #endif /*BCOPY_FASTER*/
1425a8e925d3Spk
1426a8e925d3Spk color = RAS_GETCOLOR( rop );
1427a8e925d3Spk if ( color == 0 )
1428a8e925d3Spk color = 255;
1429a8e925d3Spk
1430a8e925d3Spk /* Make 32 bits of color so we can do the ROP without shifting. */
1431a8e925d3Spk color |= ( color << 24 ) | ( color << 16 ) | ( color << 8 );
1432a8e925d3Spk
1433a8e925d3Spk dstleftignore = ( dx & 3 ) * 8;
1434a8e925d3Spk dstlongs = ( dstleftignore + w * 8 + 31 ) >> 5;
1435a8e925d3Spk dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
1436a8e925d3Spk
1437a8e925d3Spk dstlin2 = dstlin1 + h * dst->linelongs;
1438a8e925d3Spk dstlin = dstlin1;
1439a8e925d3Spk
1440a8e925d3Spk if ( dstlongs == 1 )
1441a8e925d3Spk {
1442a8e925d3Spk /* It fits into a single longword. */
1443a8e925d3Spk lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1444a8e925d3Spk nlm = ~lm;
1445a8e925d3Spk while ( dstlin != dstlin2 )
1446a8e925d3Spk {
1447a8e925d3Spk ROP_DSTCOLOR(
1448a8e925d3Spk /*op*/ op,
1449a8e925d3Spk /*pre*/ dl = *dstlin;,
1450a8e925d3Spk /*d*/ dl,
1451a8e925d3Spk /*c*/ color,
1452a8e925d3Spk /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1453a8e925d3Spk
1454a8e925d3Spk dstlin += dst->linelongs;
1455a8e925d3Spk }
1456a8e925d3Spk }
1457a8e925d3Spk else
1458a8e925d3Spk {
1459a8e925d3Spk lm = leftmask[dstleftignore];
1460a8e925d3Spk rm = rightmask[dstrightignore];
1461a8e925d3Spk nrm = ~rm;
1462a8e925d3Spk nlm = ~lm;
1463a8e925d3Spk while ( dstlin != dstlin2 )
1464a8e925d3Spk {
1465a8e925d3Spk dstlong = dstlin;
1466a8e925d3Spk dstlong2 = dstlong + dstlongs;
1467a8e925d3Spk if ( dstrightignore != 0 )
1468a8e925d3Spk --dstlong2;
1469a8e925d3Spk
1470a8e925d3Spk /* Leading edge. */
1471a8e925d3Spk if ( dstleftignore != 0 )
1472a8e925d3Spk {
1473a8e925d3Spk ROP_DSTCOLOR(
1474a8e925d3Spk /*op*/ op,
1475a8e925d3Spk /*pre*/ dl = *dstlong;,
1476a8e925d3Spk /*d*/ dl,
1477a8e925d3Spk /*c*/ color,
1478a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1479a8e925d3Spk ++dstlong;
1480a8e925d3Spk }
1481a8e925d3Spk
1482a8e925d3Spk /* Main rop. */
1483a8e925d3Spk ROP_DSTCOLOR(
1484a8e925d3Spk /*op*/ op,
1485a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1486a8e925d3Spk {,
1487a8e925d3Spk /*d*/ *dstlong,
1488a8e925d3Spk /*c*/ color,
1489a8e925d3Spk /*pst*/ ++dstlong;
1490a8e925d3Spk } )
1491a8e925d3Spk
1492a8e925d3Spk /* Trailing edge. */
1493a8e925d3Spk if ( dstrightignore != 0 )
1494a8e925d3Spk {
1495a8e925d3Spk ROP_DSTCOLOR(
1496a8e925d3Spk /*op*/ op,
1497a8e925d3Spk /*pre*/ dl = *dstlong;,
1498a8e925d3Spk /*d*/ dl,
1499a8e925d3Spk /*c*/ color,
1500a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1501a8e925d3Spk }
1502a8e925d3Spk
1503a8e925d3Spk dstlin += dst->linelongs;
1504a8e925d3Spk }
1505a8e925d3Spk }
1506a8e925d3Spk }
15079d326d48Sdbj #ifdef RCONS_16BPP
15089d326d48Sdbj else
15099d326d48Sdbj {
15109d326d48Sdbj /* Sixteen-bit no-src blit. */
1511169ac5b3Saugustss u_int32_t color;
15129d326d48Sdbj u_int32_t* dstlin1;
15139d326d48Sdbj u_int32_t* dstlin2;
15149d326d48Sdbj u_int32_t* dstlin;
15159d326d48Sdbj int dstleftignore, dstrightignore, dstlongs;
15169d326d48Sdbj u_int32_t dl, lm, nlm, rm, nrm;
1517169ac5b3Saugustss u_int32_t* dstlong2;
1518169ac5b3Saugustss u_int32_t* dstlong;
15199d326d48Sdbj
15209d326d48Sdbj dstlin1 = RAS_ADDR( dst, dx, dy );
15219d326d48Sdbj
15229d326d48Sdbj #ifdef BCOPY_FASTER
15239d326d48Sdbj /* Special-case full-width clears. */
15249d326d48Sdbj if ( op == RAS_CLEAR && dst->width == w && dst->linelongs == w >> 1 )
15259d326d48Sdbj {
1526c363a9cbScegger memset( (char*) dstlin1, 0, h * dst->linelongs * sizeof(u_int32_t) );
15279d326d48Sdbj return 0;
15289d326d48Sdbj }
15299d326d48Sdbj #endif /*BCOPY_FASTER*/
15309d326d48Sdbj
15319d326d48Sdbj color = RAS_GETCOLOR( rop );
15329d326d48Sdbj if ( color == 0 )
15339a37177dSdeberg color = 0xffff; /* XXX */
15349d326d48Sdbj
15359d326d48Sdbj /* Make 32 bits of color so we can do the ROP without shifting. */
15369d326d48Sdbj color |= ( color << 16 );
15379d326d48Sdbj
15389d326d48Sdbj dstleftignore = ( dx & 1 ) * 16;
15399d326d48Sdbj dstlongs = ( dstleftignore + w * 16 + 31 ) >> 5;
15409d326d48Sdbj dstrightignore = ( dstlongs * 32 - w * 8 - dstleftignore ) & 31;
15419d326d48Sdbj
15429d326d48Sdbj dstlin2 = dstlin1 + h * dst->linelongs;
15439d326d48Sdbj dstlin = dstlin1;
15449d326d48Sdbj
15459d326d48Sdbj if ( dstlongs == 1 )
15469d326d48Sdbj {
15479d326d48Sdbj /* It fits into a single longword. */
15489d326d48Sdbj lm = leftmask[dstleftignore] | rightmask[dstrightignore];
15499d326d48Sdbj nlm = ~lm;
15509d326d48Sdbj while ( dstlin != dstlin2 )
15519d326d48Sdbj {
15529d326d48Sdbj ROP_DSTCOLOR(
15539d326d48Sdbj /*op*/ op,
15549d326d48Sdbj /*pre*/ dl = *dstlin;,
15559d326d48Sdbj /*d*/ dl,
15569d326d48Sdbj /*c*/ color,
15579d326d48Sdbj /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
15589d326d48Sdbj
15599d326d48Sdbj dstlin += dst->linelongs;
15609d326d48Sdbj }
15619d326d48Sdbj }
15629d326d48Sdbj else
15639d326d48Sdbj {
15649d326d48Sdbj lm = leftmask[dstleftignore];
15659d326d48Sdbj rm = rightmask[dstrightignore];
15669d326d48Sdbj nrm = ~rm;
15679d326d48Sdbj nlm = ~lm;
15689d326d48Sdbj while ( dstlin != dstlin2 )
15699d326d48Sdbj {
15709d326d48Sdbj dstlong = dstlin;
15719d326d48Sdbj dstlong2 = dstlong + dstlongs;
15729d326d48Sdbj if ( dstrightignore != 0 )
15739d326d48Sdbj --dstlong2;
15749d326d48Sdbj
15759d326d48Sdbj /* Leading edge. */
15769d326d48Sdbj if ( dstleftignore != 0 )
15779d326d48Sdbj {
15789d326d48Sdbj ROP_DSTCOLOR(
15799d326d48Sdbj /*op*/ op,
15809d326d48Sdbj /*pre*/ dl = *dstlong;,
15819d326d48Sdbj /*d*/ dl,
15829d326d48Sdbj /*c*/ color,
15839d326d48Sdbj /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
15849d326d48Sdbj ++dstlong;
15859d326d48Sdbj }
15869d326d48Sdbj
15879d326d48Sdbj /* Main rop. */
15889d326d48Sdbj ROP_DSTCOLOR(
15899d326d48Sdbj /*op*/ op,
15909d326d48Sdbj /*pre*/ while ( dstlong != dstlong2 )
15919d326d48Sdbj {,
15929d326d48Sdbj /*d*/ *dstlong,
15939d326d48Sdbj /*c*/ color,
15949d326d48Sdbj /*pst*/ ++dstlong;
15959d326d48Sdbj } )
15969d326d48Sdbj
15979d326d48Sdbj /* Trailing edge. */
15989d326d48Sdbj if ( dstrightignore != 0 )
15999d326d48Sdbj {
16009d326d48Sdbj ROP_DSTCOLOR(
16019d326d48Sdbj /*op*/ op,
16029d326d48Sdbj /*pre*/ dl = *dstlong;,
16039d326d48Sdbj /*d*/ dl,
16049d326d48Sdbj /*c*/ color,
16059d326d48Sdbj /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
16069d326d48Sdbj }
16079d326d48Sdbj
16089d326d48Sdbj dstlin += dst->linelongs;
16099d326d48Sdbj }
16109d326d48Sdbj }
16119d326d48Sdbj }
16129d326d48Sdbj #endif /* RCONS_16BPP */
1613a8e925d3Spk
1614a8e925d3Spk return 0;
1615a8e925d3Spk }
1616a8e925d3Spk
1617a8e925d3Spk /* This is a general bitblit routine, handling overlapping source and
1618a8e925d3Spk ** destination. It's used for both the 1-to-1 and 8-to-8 cases.
1619a8e925d3Spk */
1620a8e925d3Spk static int
raster_blit(struct raster * src,uint32_t * srclin1,int srcleftignore,int srcrightignore,int srclongs,struct raster * dst,uint32_t * dstlin1,int dstleftignore,int dstrightignore,int dstlongs,int h,int op)1621*91d94812Smatt raster_blit(
1622*91d94812Smatt struct raster* src, uint32_t* srclin1,
1623*91d94812Smatt int srcleftignore, int srcrightignore, int srclongs,
1624*91d94812Smatt struct raster* dst,
1625*91d94812Smatt uint32_t* dstlin1,
1626*91d94812Smatt int dstleftignore, int dstrightignore, int dstlongs,
1627*91d94812Smatt int h, int op)
1628a8e925d3Spk {
1629540ab1b8Scgd u_int32_t* srclin2;
1630540ab1b8Scgd u_int32_t* dstlin2;
1631a8e925d3Spk int srclininc, dstlininc;
1632540ab1b8Scgd u_int32_t* srclin;
1633540ab1b8Scgd u_int32_t* dstlin;
1634169ac5b3Saugustss int prevleftshift, currrightshift;
1635a8e925d3Spk int longinc;
1636169ac5b3Saugustss u_int32_t* srclong;
1637169ac5b3Saugustss u_int32_t* dstlong;
1638169ac5b3Saugustss u_int32_t* dstlong2;
1639169ac5b3Saugustss u_int32_t dl, lm, nlm, rm, nrm;
1640a8e925d3Spk
1641a8e925d3Spk prevleftshift = ( srcleftignore - dstleftignore ) & 31;
1642a8e925d3Spk
1643a8e925d3Spk srclin2 = srclin1 + h * src->linelongs;
1644a8e925d3Spk dstlin2 = dstlin1 + h * dst->linelongs;
1645a8e925d3Spk srclininc = src->linelongs;
1646a8e925d3Spk dstlininc = dst->linelongs;
1647a8e925d3Spk longinc = 1;
1648a8e925d3Spk
1649a8e925d3Spk /* Check for overlaps. */
1650a8e925d3Spk if ( ( dstlin1 >= srclin1 && dstlin1 < srclin1 + srclongs ) ||
1651a8e925d3Spk ( srclin1 >= dstlin1 && srclin1 < dstlin1 + dstlongs ) )
1652a8e925d3Spk {
1653a8e925d3Spk /* Horizontal overlap. Should we reverse? */
1654a8e925d3Spk if ( srclin1 < dstlin1 )
1655a8e925d3Spk {
1656a8e925d3Spk longinc = -1;
1657a8e925d3Spk srclin1 += srclongs - 1;
1658a8e925d3Spk srclin2 += srclongs - 1;
1659a8e925d3Spk dstlin1 += dstlongs - 1;
1660a8e925d3Spk }
1661a8e925d3Spk }
1662a8e925d3Spk else if ( ( dstlin1 >= srclin1 && dstlin1 < srclin2 ) ||
1663a8e925d3Spk ( srclin1 >= dstlin1 && srclin1 < dstlin2 ) )
1664a8e925d3Spk {
1665a8e925d3Spk /* Vertical overlap. Should we reverse? */
1666a8e925d3Spk if ( srclin1 < dstlin1 )
1667a8e925d3Spk {
1668a8e925d3Spk srclin2 = srclin1 - srclininc;
1669a8e925d3Spk srclin1 += ( h - 1 ) * srclininc;
1670a8e925d3Spk dstlin1 += ( h - 1 ) * dstlininc;
1671a8e925d3Spk srclininc = -srclininc;
1672a8e925d3Spk dstlininc = -dstlininc;
1673a8e925d3Spk }
1674a8e925d3Spk }
1675a8e925d3Spk srclin = srclin1;
1676a8e925d3Spk dstlin = dstlin1;
1677a8e925d3Spk
1678a8e925d3Spk if ( prevleftshift == 0 )
1679a8e925d3Spk {
1680a8e925d3Spk /* The bits line up, no shifting necessary. */
1681a8e925d3Spk if ( dstlongs == 1 )
1682a8e925d3Spk {
1683a8e925d3Spk /* It all fits into a single longword. */
1684a8e925d3Spk lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1685a8e925d3Spk nlm = ~lm;
1686a8e925d3Spk while ( srclin != srclin2 )
1687a8e925d3Spk {
1688a8e925d3Spk ROP_SRCDST(
1689a8e925d3Spk /*op*/ op,
1690a8e925d3Spk /*pre*/ dl = *dstlin;,
1691a8e925d3Spk /*s*/ *srclin,
1692a8e925d3Spk /*d*/ dl,
1693a8e925d3Spk /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1694a8e925d3Spk
1695a8e925d3Spk srclin += srclininc;
1696a8e925d3Spk dstlin += dstlininc;
1697a8e925d3Spk }
1698a8e925d3Spk }
1699a8e925d3Spk else
1700a8e925d3Spk {
1701a8e925d3Spk /* Multiple longwords. */
1702a8e925d3Spk lm = leftmask[dstleftignore];
1703a8e925d3Spk rm = rightmask[dstrightignore];
1704a8e925d3Spk nrm = ~rm;
1705a8e925d3Spk nlm = ~lm;
1706a8e925d3Spk if ( longinc == 1 )
1707a8e925d3Spk {
1708a8e925d3Spk /* Left to right. */
1709a8e925d3Spk while ( srclin != srclin2 )
1710a8e925d3Spk {
1711a8e925d3Spk srclong = srclin;
1712a8e925d3Spk dstlong = dstlin;
1713a8e925d3Spk dstlong2 = dstlong + dstlongs;
1714a8e925d3Spk if ( dstrightignore != 0 )
1715a8e925d3Spk --dstlong2;
1716a8e925d3Spk
1717a8e925d3Spk /* Leading edge. */
1718a8e925d3Spk if ( dstleftignore != 0 )
1719a8e925d3Spk {
1720a8e925d3Spk ROP_SRCDST(
1721a8e925d3Spk /*op*/ op,
1722a8e925d3Spk /*pre*/ dl = *dstlong;,
1723a8e925d3Spk /*s*/ *srclong,
1724a8e925d3Spk /*d*/ dl,
1725a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1726a8e925d3Spk ++srclong;
1727a8e925d3Spk ++dstlong;
1728a8e925d3Spk }
1729a8e925d3Spk
1730a8e925d3Spk /* Main rop. */
1731a8e925d3Spk ROP_SRCDST(
1732a8e925d3Spk /*op*/ op,
1733a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1734a8e925d3Spk {,
1735a8e925d3Spk /*s*/ *srclong,
1736a8e925d3Spk /*d*/ *dstlong,
1737a8e925d3Spk /*pst*/ ++srclong;
1738a8e925d3Spk ++dstlong;
1739a8e925d3Spk } )
1740a8e925d3Spk
1741a8e925d3Spk /* Trailing edge. */
1742a8e925d3Spk if ( dstrightignore != 0 )
1743a8e925d3Spk {
1744a8e925d3Spk ROP_SRCDST(
1745a8e925d3Spk /*op*/ op,
1746a8e925d3Spk /*pre*/ dl = *dstlong;,
1747a8e925d3Spk /*s*/ *srclong,
1748a8e925d3Spk /*d*/ dl,
1749a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1750a8e925d3Spk }
1751a8e925d3Spk
1752a8e925d3Spk srclin += srclininc;
1753a8e925d3Spk dstlin += dstlininc;
1754a8e925d3Spk }
1755a8e925d3Spk }
1756a8e925d3Spk else
1757a8e925d3Spk {
1758a8e925d3Spk /* Right to left. */
1759a8e925d3Spk while ( srclin != srclin2 )
1760a8e925d3Spk {
1761a8e925d3Spk srclong = srclin;
1762a8e925d3Spk dstlong = dstlin;
1763a8e925d3Spk dstlong2 = dstlong - dstlongs;
1764a8e925d3Spk if ( dstleftignore != 0 )
1765a8e925d3Spk ++dstlong2;
1766a8e925d3Spk
1767a8e925d3Spk /* Leading edge. */
1768a8e925d3Spk if ( dstrightignore != 0 )
1769a8e925d3Spk {
1770a8e925d3Spk ROP_SRCDST(
1771a8e925d3Spk /*op*/ op,
1772a8e925d3Spk /*pre*/ dl = *dstlong;,
1773a8e925d3Spk /*s*/ *srclong,
1774a8e925d3Spk /*d*/ dl,
1775a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1776a8e925d3Spk --srclong;
1777a8e925d3Spk --dstlong;
1778a8e925d3Spk }
1779a8e925d3Spk
1780a8e925d3Spk /* Main rop. */
1781a8e925d3Spk ROP_SRCDST(
1782a8e925d3Spk /*op*/ op,
1783a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1784a8e925d3Spk {,
1785a8e925d3Spk /*s*/ *srclong,
1786a8e925d3Spk /*d*/ *dstlong,
1787a8e925d3Spk /*pst*/ --srclong;
1788a8e925d3Spk --dstlong;
1789a8e925d3Spk } )
1790a8e925d3Spk
1791a8e925d3Spk /* Trailing edge. */
1792a8e925d3Spk if ( dstleftignore != 0 )
1793a8e925d3Spk {
1794a8e925d3Spk ROP_SRCDST(
1795a8e925d3Spk /*op*/ op,
1796a8e925d3Spk /*pre*/ dl = *dstlong;,
1797a8e925d3Spk /*s*/ *srclong,
1798a8e925d3Spk /*d*/ dl,
1799a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1800a8e925d3Spk }
1801a8e925d3Spk
1802a8e925d3Spk srclin += srclininc;
1803a8e925d3Spk dstlin += dstlininc;
1804a8e925d3Spk }
1805a8e925d3Spk }
1806a8e925d3Spk }
1807a8e925d3Spk }
1808a8e925d3Spk
1809a8e925d3Spk else
1810a8e925d3Spk {
1811a8e925d3Spk /* General case, with shifting and everything. */
1812169ac5b3Saugustss u_int32_t sl, prevsl;
1813a8e925d3Spk
1814a8e925d3Spk currrightshift = 32 - prevleftshift;
1815a8e925d3Spk if ( srclongs == 1 && dstlongs == 1 )
1816a8e925d3Spk {
1817a8e925d3Spk /* It fits into a single longword, with a shift. */
1818a8e925d3Spk lm = leftmask[dstleftignore] | rightmask[dstrightignore];
1819a8e925d3Spk nlm = ~lm;
1820a8e925d3Spk if ( srcleftignore > dstleftignore )
1821a8e925d3Spk {
1822a8e925d3Spk while ( srclin != srclin2 )
1823a8e925d3Spk {
1824a8e925d3Spk ROP_SRCDST(
1825a8e925d3Spk /*op*/ op,
1826a8e925d3Spk /*pre*/ dl = *dstlin;,
18273b2862c8Spk /*s*/ *srclin LSOP prevleftshift,
1828a8e925d3Spk /*d*/ dl,
1829a8e925d3Spk /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1830a8e925d3Spk
1831a8e925d3Spk srclin += srclininc;
1832a8e925d3Spk dstlin += dstlininc;
1833a8e925d3Spk }
1834a8e925d3Spk }
1835a8e925d3Spk else
1836a8e925d3Spk {
1837a8e925d3Spk while ( srclin != srclin2 )
1838a8e925d3Spk {
1839a8e925d3Spk ROP_SRCDST(
1840a8e925d3Spk /*op*/ op,
1841a8e925d3Spk /*pre*/ dl = *dstlin;,
18423b2862c8Spk /*s*/ *srclin RSOP currrightshift,
1843a8e925d3Spk /*d*/ dl,
1844a8e925d3Spk /*pst*/ *dstlin = ( *dstlin & lm ) | ( dl & nlm ); )
1845a8e925d3Spk
1846a8e925d3Spk srclin += srclininc;
1847a8e925d3Spk dstlin += dstlininc;
1848a8e925d3Spk }
1849a8e925d3Spk }
1850a8e925d3Spk }
1851a8e925d3Spk else
1852a8e925d3Spk {
1853a8e925d3Spk /* Multiple longwords. */
1854a8e925d3Spk lm = leftmask[dstleftignore];
1855a8e925d3Spk rm = rightmask[dstrightignore];
1856a8e925d3Spk nrm = ~rm;
1857a8e925d3Spk nlm = ~lm;
1858a8e925d3Spk if ( longinc == 1 )
1859a8e925d3Spk {
1860a8e925d3Spk /* Left to right. */
1861a8e925d3Spk while ( srclin != srclin2 )
1862a8e925d3Spk {
1863a8e925d3Spk srclong = srclin;
1864a8e925d3Spk dstlong = dstlin;
1865a8e925d3Spk dstlong2 = dstlong + dstlongs;
1866a8e925d3Spk if ( srcleftignore > dstleftignore )
18673b2862c8Spk prevsl = *srclong++ LSOP prevleftshift;
1868a8e925d3Spk else
1869a8e925d3Spk prevsl = 0;
1870a8e925d3Spk if ( dstrightignore != 0 )
1871a8e925d3Spk --dstlong2;
1872a8e925d3Spk
1873a8e925d3Spk /* Leading edge. */
1874a8e925d3Spk if ( dstleftignore != 0 )
1875a8e925d3Spk {
1876a8e925d3Spk ROP_SRCDST(
1877a8e925d3Spk /*op*/ op,
1878a8e925d3Spk /*pre*/ sl = *srclong;
1879a8e925d3Spk dl = *dstlong;,
18803b2862c8Spk /*s*/ prevsl | ( sl RSOP currrightshift ),
1881a8e925d3Spk /*d*/ dl,
1882a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1883f64a09cfSthorpej prevsl = sl LSOP prevleftshift;
1884a8e925d3Spk ++srclong;
1885a8e925d3Spk ++dstlong;
1886a8e925d3Spk }
1887a8e925d3Spk
1888a8e925d3Spk /* Main rop. */
1889a8e925d3Spk ROP_SRCDST(
1890a8e925d3Spk /*op*/ op,
1891a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1892a8e925d3Spk {
1893a8e925d3Spk sl = *srclong;,
18943b2862c8Spk /*s*/ prevsl | ( sl RSOP currrightshift ),
1895a8e925d3Spk /*d*/ *dstlong,
18963b2862c8Spk /*pst*/ prevsl = sl LSOP prevleftshift;
1897a8e925d3Spk ++srclong;
1898a8e925d3Spk ++dstlong;
1899a8e925d3Spk } )
1900a8e925d3Spk
1901a8e925d3Spk /* Trailing edge. */
1902a8e925d3Spk if ( dstrightignore != 0 )
1903a8e925d3Spk {
1904a8e925d3Spk ROP_SRCDST(
1905a8e925d3Spk /*op*/ op,
1906a8e925d3Spk /*pre*/ dl = *dstlong;,
19073b2862c8Spk /*s*/ prevsl | ( *srclong RSOP currrightshift ),
1908a8e925d3Spk /*d*/ dl,
1909a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
1910a8e925d3Spk }
1911a8e925d3Spk
1912a8e925d3Spk srclin += srclininc;
1913a8e925d3Spk dstlin += dstlininc;
1914a8e925d3Spk }
1915a8e925d3Spk }
1916a8e925d3Spk else
1917a8e925d3Spk {
1918a8e925d3Spk /* Right to left. */
1919a8e925d3Spk while ( srclin != srclin2 )
1920a8e925d3Spk {
1921a8e925d3Spk srclong = srclin;
1922a8e925d3Spk dstlong = dstlin;
1923a8e925d3Spk dstlong2 = dstlong - dstlongs;
1924a8e925d3Spk if ( srcrightignore > dstrightignore )
19253b2862c8Spk prevsl = *srclong-- RSOP currrightshift;
1926a8e925d3Spk else
1927a8e925d3Spk prevsl = 0;
1928a8e925d3Spk if ( dstleftignore != 0 )
1929a8e925d3Spk ++dstlong2;
1930a8e925d3Spk
1931a8e925d3Spk /* Leading edge. */
1932a8e925d3Spk if ( dstrightignore != 0 )
1933a8e925d3Spk {
1934a8e925d3Spk ROP_SRCDST(
1935a8e925d3Spk /*op*/ op,
1936a8e925d3Spk /*pre*/ sl = *srclong;
1937a8e925d3Spk dl = *dstlong;,
19383b2862c8Spk /*s*/ prevsl | ( sl LSOP prevleftshift ),
1939a8e925d3Spk /*d*/ dl,
1940a8e925d3Spk /*pst*/ *dstlong = ( dl & nrm ) | ( *dstlong & rm ); )
19413b2862c8Spk prevsl = sl RSOP currrightshift;
1942a8e925d3Spk --srclong;
1943a8e925d3Spk --dstlong;
1944a8e925d3Spk }
1945a8e925d3Spk
1946a8e925d3Spk /* Main rop. */
1947a8e925d3Spk ROP_SRCDST(
1948a8e925d3Spk /*op*/ op,
1949a8e925d3Spk /*pre*/ while ( dstlong != dstlong2 )
1950a8e925d3Spk {
1951a8e925d3Spk sl = *srclong;,
19523b2862c8Spk /*s*/ prevsl | ( sl LSOP prevleftshift ),
1953a8e925d3Spk /*d*/ *dstlong,
19543b2862c8Spk /*pst*/ prevsl = sl RSOP currrightshift;
1955a8e925d3Spk --srclong;
1956a8e925d3Spk --dstlong;
1957a8e925d3Spk } )
1958a8e925d3Spk
1959a8e925d3Spk /* Trailing edge. */
1960a8e925d3Spk if ( dstleftignore != 0 )
1961a8e925d3Spk {
1962a8e925d3Spk ROP_SRCDST(
1963a8e925d3Spk /*op*/ op,
1964a8e925d3Spk /*pre*/ dl = *dstlong;,
19653b2862c8Spk /*s*/ prevsl | ( *srclong LSOP prevleftshift ),
1966a8e925d3Spk /*d*/ dl,
1967a8e925d3Spk /*pst*/ *dstlong = ( *dstlong & lm ) | ( dl & nlm ); )
1968a8e925d3Spk }
1969a8e925d3Spk
1970a8e925d3Spk srclin += srclininc;
1971a8e925d3Spk dstlin += dstlininc;
1972a8e925d3Spk }
1973a8e925d3Spk }
1974a8e925d3Spk }
1975a8e925d3Spk }
1976a8e925d3Spk
1977a8e925d3Spk return 0;
1978a8e925d3Spk }
1979