]> git.sesse.net Git - ccbs/blob - bigscreen/tinyptc/mmx.s
Fixed a misleading comment.
[ccbs] / bigscreen / tinyptc / mmx.s
1 ;
2 ; TinyPTC x11 v0.7.3 MMX-Optimized pixelformat converters
3 ; Copyright (C) 2000-2002 Alessandro Gatti <a.gatti@tiscali.it>
4 ; Copyright (C) 2000-2001 Glenn Fiedler <gaffer@gaffer.org>
5 ;
6 ; http://www.sourceforge.net/projects/tinyptc/
7 ;
8 ; This library is free software; you can redistribute it and/or
9 ; modify it under the terms of the GNU Lesser General Public
10 ; License as published by the Free Software Foundation; either
11 ; version 2 of the License, or (at your option) any later version.
12 ;
13 ; This library is distributed in the hope that it will be useful,
14 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ; Lesser General Public License for more details.
17 ;
18 ; You should have received a copy of the GNU Lesser General Public
19 ; License along with this library; if not, write to the Free Software
20 ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22
23 %include "mmx.i"
24
25 bits 32
26
27 %ifdef __PTC_MMX__
28 global mmx_memcpy
29 %endif
30
31 %ifdef __PTC_MMX_CONVERT_32_TO_32_BGR888
32 global mmx_convert_32_to_32_bgr888
33 %endif
34
35 %ifdef __PTC_MMX_CONVERT_32_TO_24_RGB888
36 global mmx_convert_32_to_24_rgb888
37 %endif
38
39 %ifdef __PTC_MMX_CONVERT_32_TO_24_BGR888
40 global mmx_convert_32_to_24_bgr888
41 %endif 
42
43 %ifdef __PTC_MMX_CONVERT_32_TO_16_RGB565
44 global mmx_convert_32_to_16_rgb565
45 %endif
46
47 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR565
48 global mmx_convert_32_to_16_bgr565
49 %endif
50
51 %ifdef __PTC_MMX_CONVERT_32_TO_16_RGB555
52 global mmx_convert_32_to_16_rgb555
53 %endif
54
55 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR555
56 global mmx_convert_32_to_16_bgr555
57 %endif
58
59 section .data
60
61 align 16
62
63 mmx_rgb888_mask dd 00ffffffh,00ffffffh
64
65 mmx_rgb565_b dd 000000f8h, 000000f8h
66 mmx_rgb565_g dd 0000fc00h, 0000fc00h
67 mmx_rgb565_r dd 00f80000h, 00f80000h
68
69 mmx_rgb555_rb dd 00f800f8h,00f800f8h
70 mmx_rgb555_g dd 0000f800h,0000f800h
71 mmx_rgb555_mul dd 20000008h,20000008h
72 mmx_bgr555_mul dd 00082000h,00082000h
73
74 section .text
75
76 %ifdef __PTC_MMX__
77
78 align 16
79
80 mmx_memcpy:
81
82     push ebp
83     mov ebp,esp
84
85     pushad
86
87     mov edi,[ebp+8]       ; destination
88     mov esi,[ebp+12]      ; source
89     mov ecx,[ebp+16]      ; bytes
90
91     mov eax,ecx
92     shr ecx,6
93     mov ebx,ecx
94     shl ebx,6
95     sub eax,ebx
96
97 align 16
98              
99     .loop
100
101         movq mm0,[esi]
102         movq mm1,[esi+8]
103         movq mm2,[esi+16]
104         movq mm3,[esi+24]
105         movq mm4,[esi+32]
106         movq mm5,[esi+40]
107         movq mm6,[esi+48]
108         movq mm7,[esi+56]
109         movq [edi],mm0
110         movq [edi+8],mm1
111         movq [edi+16],mm2
112         movq [edi+24],mm3
113         movq [edi+32],mm4
114         movq [edi+40],mm5
115         movq [edi+48],mm6
116         movq [edi+56],mm7
117         add esi,8*8
118         add edi,8*8
119         dec ecx
120         jnz .loop
121
122     mov ecx,eax
123     rep movsb
124
125     emms
126
127     popad
128     
129     pop ebp
130     ret
131
132 %endif
133
134 %ifdef __PTC_MMX_CONVERT_32_TO_32_BGR888
135
136 align 16
137
138 mmx_convert_32_to_32_bgr888:
139
140     ret
141
142 %endif
143
144 %ifdef __PTC_MMX_CONVERT_32_TO_24_RGB888
145
146
147 align 16
148
149 mmx_convert_32_to_24_rgb888:
150
151     push ebp
152     mov ebp,esp
153
154     pushad
155
156     mov edi,[ebp+8]       ; destination
157     mov esi,[ebp+12]      ; source
158     mov ecx,[ebp+16]      ; bytes
159
160     ; set up mm6 as the mask, mm7 as zero
161     movq mm6, qword [mmx_rgb888_mask]
162     pxor mm7, mm7
163
164     mov edx, ecx                    ; save ecx
165     and ecx, 0fffffffch             ; clear lower two bits
166     jnz .L1
167     jmp .L2
168
169 .L1:
170
171     movq mm0, [esi]                 ; A R G B a r g b
172     pand mm0, mm6                   ; 0 R G B 0 r g b
173     movq mm1, [esi+8]               ; A R G B a r g b
174     pand mm1, mm6                   ; 0 R G B 0 r g b
175
176     movq mm2, mm0                   ; 0 R G B 0 r g b
177     punpckhdq mm2, mm7              ; 0 0 0 0 0 R G B
178     punpckldq mm0, mm7              ; 0 0 0 0 0 r g b
179     psllq mm2, 24                   ; 0 0 R G B 0 0 0
180     por mm0, mm2                    ; 0 0 R G B r g b
181
182     movq mm3, mm1                   ; 0 R G B 0 r g b
183     psllq mm3, 48                   ; g b 0 0 0 0 0 0
184     por mm0, mm3                    ; g b R G B r g b
185
186     movq mm4, mm1                   ; 0 R G B 0 r g b
187     punpckhdq mm4, mm7              ; 0 0 0 0 0 R G B
188     punpckldq mm1, mm7              ; 0 0 0 0 0 r g b
189     psrlq mm1, 16                   ; 0 0 0 R G B 0 r
190     psllq mm4, 8                    ; 0 0 0 0 R G B 0
191     por mm1, mm4                    ; 0 0 0 0 R G B r
192
193     movq [edi], mm0
194     add esi, BYTE 16
195     movd [edi+8], mm1
196     add edi, BYTE 12
197     sub ecx, BYTE 4
198     jnz .L1
199
200 .L2:
201     mov ecx, edx
202     and ecx, BYTE 3
203     jz .L4
204 .L3:
205     mov al, [esi]
206     mov bl, [esi+1]
207     mov dl, [esi+2]
208     mov [edi], al
209     mov [edi+1], bl
210     mov [edi+2], dl
211     add esi, BYTE 4
212     add edi, BYTE 3
213     dec ecx
214     jnz .L3
215 .L4:
216
217     emms
218
219     popad
220     
221     pop ebp
222     ret
223
224 %endif
225
226 %ifdef __PTC_MMX_CONVERT_32_TO_24_BGR888
227
228 align 16
229
230 mmx_convert_32_to_24_bgr888:
231
232     ret
233
234 %endif
235
236
237 %ifdef __PTC_MMX_CONVERT_32_TO_16_RGB565
238
239 align 16
240
241 mmx_convert_32_to_16_rgb565:
242
243     push ebp
244     mov ebp,esp
245
246     pushad
247
248     mov edi,[ebp+8]       ; destination
249     mov esi,[ebp+12]      ; source
250     mov ecx,[ebp+16]      ; bytes
251
252     ; set up masks
253     movq mm5, [mmx_rgb565_b]
254     movq mm6, [mmx_rgb565_g]
255     movq mm7, [mmx_rgb565_r]
256
257     mov edx, ecx
258     shr ecx, 2
259     jnz .L1
260     jmp .L2         ; not necessary at the moment, but doesn't hurt (much)
261
262 .L1:
263     movq mm0, [esi]         ; argb
264     movq mm1, mm0           ; argb
265     pand mm0, mm6           ; 00g0
266     movq mm3, mm1           ; argb
267     pand mm1, mm5           ; 000b
268     pand mm3, mm7           ; 0r00
269     pslld mm1, 2            ; 0 0 000000bb bbb00000
270     por mm0, mm1            ; 0 0 ggggggbb bbb00000
271     psrld mm0, 5            ; 0 0 00000ggg gggbbbbb
272
273     movq mm4, [esi+8]       ; argb
274     movq mm2, mm4           ; argb
275     pand mm4, mm6           ; 00g0
276     movq mm1, mm2           ; argb
277     pand mm2, mm5           ; 000b
278     pand mm1, mm7           ; 0r00
279     pslld mm2, 2            ; 0 0 000000bb bbb00000
280     por mm4, mm2            ; 0 0 ggggggbb bbb00000
281     psrld mm4, 5            ; 0 0 00000ggg gggbbbbb
282
283     packuswb mm3, mm1       ; R 0 r 0
284     packssdw mm0, mm4       ; as above.. ish
285     por mm0, mm3            ; done.
286     movq [edi], mm0
287
288     add esi, 16
289     add edi, 8
290     dec ecx
291     jnz .L1
292
293 .L2:
294     mov ecx, edx
295     and ecx, BYTE 3
296     jz .L4
297 .L3:
298     mov al, [esi]
299     mov bh, [esi+1]
300     mov ah, [esi+2]
301     shr al, 3
302     and eax, 0F81Fh            ; BYTE?
303     shr ebx, 5
304     and ebx, 07E0h             ; BYTE?
305     add eax, ebx
306     mov [edi], al
307     mov [edi+1], ah
308     add esi, BYTE 4
309     add edi, BYTE 2
310     dec ecx
311     jnz .L3
312
313 .L4:
314
315     emms
316
317     popad
318     
319     pop ebp
320     ret
321
322 %endif
323
324 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR565
325
326 align 16
327
328 mmx_convert_32_to_16_bgr565:
329
330     push ebp
331     mov ebp,esp
332
333     pushad
334
335     mov edi,[ebp+8]       ; destination
336     mov esi,[ebp+12]      ; source
337     mov ecx,[ebp+16]      ; bytes
338
339     movq mm5, [mmx_rgb565_r]
340     movq mm6, [mmx_rgb565_g]
341     movq mm7, [mmx_rgb565_b]
342
343     mov edx, ecx
344     shr ecx, 2
345     jnz .L1
346     jmp .L2
347
348 .L1:
349     movq mm0, [esi]                 ; a r g b
350     movq mm1, mm0                   ; a r g b
351     pand mm0, mm6                   ; 0 0 g 0
352     movq mm3, mm1                   ; a r g b
353     pand mm1, mm5                   ; 0 r 0 0
354     pand mm3, mm7                   ; 0 0 0 b
355
356     psllq mm3, 16                   ; 0 b 0 0
357     psrld mm1, 14                   ; 0 0 000000rr rrr00000
358     por mm0, mm1                    ; 0 0 ggggggrr rrr00000
359     psrld mm0, 5                    ; 0 0 00000ggg gggrrrrr
360
361     movq mm4, [esi+8]               ; a r g b
362     movq mm2, mm4                   ; a r g b
363     pand mm4, mm6                   ; 0 0 g 0
364     movq mm1, mm2                   ; a r g b
365     pand mm2, mm5                   ; 0 r 0 0
366     pand mm1, mm7                   ; 0 0 0 b
367
368     psllq mm1, 16                   ; 0 b 0 0
369     psrld mm2, 14                   ; 0 0 000000rr rrr00000
370     por mm4, mm2                    ; 0 0 ggggggrr rrr00000
371     psrld mm4, 5                    ; 0 0 00000ggg gggrrrrr
372
373     packuswb mm3, mm1               ; BBBBB000 00000000 bbbbb000 00000000
374     packssdw mm0, mm4               ; 00000GGG GGGRRRRR 00000GGG GGGRRRRR
375     por mm0, mm3                    ; BBBBBGGG GGGRRRRR bbbbbggg gggrrrrr
376     movq [edi], mm0
377
378     add esi, BYTE 16
379     add edi, BYTE 8
380     dec ecx
381     jnz .L1
382
383 .L2:
384     and edx, BYTE 3
385     jz .L4
386 .L3:
387     mov al, [esi+2]
388     mov bh, [esi+1]
389     mov ah, [esi]
390     shr al, 3
391     and eax, 0F81Fh                    ; BYTE ?
392     shr ebx, 5
393     and ebx, 07E0h                     ; BYTE ?
394     add eax, ebx
395     mov [edi], al
396     mov [edi+1], ah
397     add esi, BYTE 4
398     add edi, BYTE 2
399     dec edx
400     jnz .L3
401
402 .L4:
403
404     emms
405
406     popad
407     
408     pop ebp
409     ret
410
411 %endif
412
413 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR555
414
415 align 16
416
417 mmx_convert_32_to_16_bgr555:
418
419     ; the 16BGR555 converter is identical to the RGB555 one,
420     ; except it uses a different multiplier for the pmaddwd
421     ; instruction.  cool huh.
422
423     movq mm7, qword [mmx_bgr555_mul]
424
425 %endif
426
427 %ifdef __PTC_MMX_CONVERT_32_TO_16_RGB555
428 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR555
429     jmp _convert_bgr555_cheat
430 %endif
431
432     ; This is the same as the Intel version.. they obviously went to
433     ; much more trouble to expand/coil the loop than I did, so theirs
434     ; would almost certainly be faster, even if only a little.
435     ; I did rename 'mmx_rgb555_add' to 'mmx_rgb555_mul', which is
436     ; (I think) a more accurate name..
437
438 align 16
439
440 mmx_convert_32_to_16_rgb555:
441
442     movq mm7,qword [mmx_rgb555_mul]
443
444 %endif
445
446 %ifdef __PTC_MMX_CONVERT_32_TO_16_RGB555
447 %ifdef __PTC_MMX_CONVERT_32_TO_16_BGR555
448
449 _convert_bgr555_cheat:
450
451     movq mm6,qword [mmx_rgb555_g]
452     push ebp
453     mov ebp,esp
454
455     pushad
456
457     mov edi,[ebp+8]       ; destination
458     mov esi,[ebp+12]      ; source
459     mov ecx,[ebp+16]      ; bytes
460         
461         mov edx,ecx                        ; Save ecx 
462
463     and ecx,BYTE 0fffffff8h            ; clear lower three bits
464         jnz .L_OK
465     jmp .L2 
466
467 .L_OK:
468         
469         movq mm2,[esi+8]
470
471         movq mm0,[esi]
472         movq mm3,mm2
473
474         pand mm3,qword [mmx_rgb555_rb]
475         movq mm1,mm0
476
477         pand mm1,qword [mmx_rgb555_rb]
478         pmaddwd mm3,mm7
479
480         pmaddwd mm1,mm7
481         pand mm2,mm6
482
483 .L1:
484         movq mm4,[esi+24]
485         pand mm0,mm6
486
487         movq mm5,[esi+16]
488         por mm3,mm2
489
490         psrld mm3,6
491         por mm1,mm0
492
493         movq mm0,mm4
494         psrld mm1,6
495
496         pand mm0,qword [mmx_rgb555_rb]
497         packssdw mm1,mm3
498
499         movq mm3,mm5
500         pmaddwd mm0,mm7
501
502         pand mm3,qword [mmx_rgb555_rb]
503         pand mm4,mm6
504
505         movq [edi],mm1                  
506         pmaddwd mm3,mm7
507
508         add esi,BYTE 32
509         por mm4,mm0
510
511         pand mm5,mm6
512         psrld mm4,6
513
514         movq mm2,[esi+8]
515         por mm5,mm3
516
517         movq mm0,[esi]
518         psrld mm5,6
519
520         movq mm3,mm2
521         movq mm1,mm0
522
523         pand mm3,qword [mmx_rgb555_rb]
524         packssdw mm5,mm4
525
526         pand mm1,qword [mmx_rgb555_rb]
527         pand mm2,mm6
528
529         movq [edi+8],mm5
530         pmaddwd mm3,mm7
531
532         pmaddwd mm1,mm7
533     add edi,BYTE 16
534
535     sub ecx,BYTE 8
536         jz .L2
537     jmp .L1
538
539 .L2:    
540         mov ecx,edx
541         
542     and ecx,BYTE 7
543         jz .L4
544         
545 .L3:    
546         mov ebx,[esi]
547     add esi,BYTE 4
548         
549     mov eax,ebx
550     mov edx,ebx
551
552     shr eax,3
553     shr edx,6
554
555     and eax,BYTE 0000000000011111b
556     and edx,     0000001111100000b
557
558     shr ebx,9
559
560     or eax,edx
561
562     and ebx,     0111110000000000b
563
564     or eax,ebx
565
566     mov [edi],ax
567     add edi,BYTE 2
568
569     dec ecx
570     jnz .L3     
571
572 .L4:
573
574     emms
575
576     popad
577     
578     pop ebp
579     ret
580
581 %endif
582 %endif