mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-20 19:43:01 +00:00
f006cc173d
2001-04-02 Sven Neumann <sven@gimp.org> * app/Makefile.am * app/detect_mmx.S * app/arch/i386/mmx/detect_mmx.S * app/arch/i386/mmx/paint_funcs_mmx.S * app/arch/i386/mmx/paint_funcs_mmx.S.m4: split MMX detection out of paint_funcs_mmx.S and replaced it with a working version (the old one used to execute an illegal instruction on non-MMX systems).
339 lines
5.5 KiB
Plaintext
339 lines
5.5 KiB
Plaintext
/*
|
|
MMX code to supplement some functions in paint_funcs.c
|
|
for the Gimp.
|
|
|
|
Copyright (C) 1999, 2001 David Monniaux
|
|
*/
|
|
|
|
.text
|
|
.align 4
|
|
|
|
.alpha_mask_1a: .int 0xFF00FF00, 0xFF00FF00
|
|
.mult_shift: .int 0x00800080, 0x00800080
|
|
.alpha_mask_3a: .int 0xFF000000, 0xFF000000
|
|
|
|
define(`MMX_PIXEL_OP_3A_1A', `
|
|
.globl $1_pixels_3a_3a
|
|
|
|
.align 16
|
|
$1_pixels_3a_3a:
|
|
pushl %edi
|
|
pushl %ebx
|
|
movl 12(%esp), %edi
|
|
movq .alpha_mask_3a, %mm0
|
|
$2
|
|
subl $ 2, %ecx
|
|
jl .$1_pixels_3a_3a_last
|
|
movl $ 8, %ebx
|
|
.$1_pixels_3a_3a_loop:
|
|
movq (%eax), %mm2
|
|
movq (%edx), %mm3
|
|
$3
|
|
movq %mm1, (%edi)
|
|
addl %ebx, %eax
|
|
addl %ebx, %edx
|
|
addl %ebx, %edi
|
|
subl $ 2, %ecx
|
|
jge .$1_pixels_3a_3a_loop
|
|
.$1_pixels_3a_3a_last:
|
|
test $ 1, %ecx
|
|
jz .$1_pixels_3a_3a_end
|
|
movd (%eax), %mm2
|
|
movd (%edx), %mm3
|
|
$3
|
|
movd %mm1, (%edi)
|
|
.$1_pixels_3a_3a_end:
|
|
$4
|
|
emms
|
|
popl %ebx
|
|
popl %edi
|
|
ret
|
|
|
|
.globl $1_pixels_1a_1a
|
|
.align 16
|
|
$1_pixels_1a_1a:
|
|
pushl %edi
|
|
pushl %ebx
|
|
movl 12(%esp), %edi
|
|
movq .alpha_mask_1a, %mm0
|
|
subl $ 4, %ecx
|
|
jl .$1_pixels_1a_1a_last3
|
|
movl $ 8, %ebx
|
|
.$1_pixels_1a_1a_loop:
|
|
movq (%eax), %mm2
|
|
movq (%edx), %mm3
|
|
$3
|
|
movq %mm1, (%edi)
|
|
addl %ebx, %eax
|
|
addl %ebx, %edx
|
|
addl %ebx, %edi
|
|
subl $ 4, %ecx
|
|
jge .$1_pixels_1a_1a_loop
|
|
|
|
.$1_pixels_1a_1a_last3:
|
|
test $ 2, %ecx
|
|
jz .$1_pixels_1a_1a_last1
|
|
movd (%eax), %mm2
|
|
movd (%edx), %mm3
|
|
$3
|
|
addl $ 4, %eax
|
|
addl $ 4, %edx
|
|
addl $ 4, %edi
|
|
|
|
.$1_pixels_1a_1a_last1:
|
|
test $ 1, %ecx
|
|
jz .$1_pixels_1a_1a_end
|
|
|
|
movw (%eax), %bx
|
|
movd %ebx, %mm2
|
|
movw (%edx), %bx
|
|
movd %ebx, %mm3
|
|
$3
|
|
movd %mm1, %ebx
|
|
movw %bx, (%edi)
|
|
|
|
.$1_pixels_1a_1a_end:
|
|
$4
|
|
emms
|
|
popl %ebx
|
|
popl %edi
|
|
ret')
|
|
|
|
/* min(a,b) = a - max(a-b, 0) */
|
|
MMX_PIXEL_OP_3A_1A(`add', `', `
|
|
movq %mm2, %mm4
|
|
paddusb %mm3, %mm4
|
|
movq %mm0, %mm1
|
|
pandn %mm4, %mm1
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1', `')
|
|
|
|
MMX_PIXEL_OP_3A_1A(`substract', `', `
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
movq %mm0, %mm1
|
|
pandn %mm4, %mm1
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1', `')
|
|
|
|
MMX_PIXEL_OP_3A_1A(`difference', `', `
|
|
movq %mm2, %mm4
|
|
movq %mm3, %mm5
|
|
psubusb %mm3, %mm4
|
|
psubusb %mm2, %mm5
|
|
movq %mm0, %mm1
|
|
paddb %mm5, %mm4
|
|
pandn %mm4, %mm1
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1', `')
|
|
|
|
MMX_PIXEL_OP_3A_1A(`multiply', `
|
|
movq .mult_shift, %mm7
|
|
pxor %mm6, %mm6',`
|
|
|
|
movq %mm2, %mm1
|
|
punpcklbw %mm6, %mm1
|
|
movq %mm3, %mm5
|
|
punpcklbw %mm6, %mm5
|
|
pmullw %mm5, %mm1
|
|
paddw %mm7, %mm1
|
|
movq %mm1, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm1
|
|
psrlw $ 8, %mm1
|
|
|
|
movq %mm2, %mm4
|
|
punpckhbw %mm6, %mm4
|
|
movq %mm3, %mm5
|
|
punpckhbw %mm6, %mm5
|
|
pmullw %mm5, %mm4
|
|
paddw %mm7, %mm4
|
|
movq %mm4, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm4
|
|
psrlw $ 8, %mm4
|
|
|
|
packuswb %mm4, %mm1
|
|
|
|
movq %mm0, %mm4
|
|
pandn %mm1, %mm4
|
|
movq %mm4, %mm1
|
|
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1', `')
|
|
|
|
/* Could be perhaps more optimized */
|
|
MMX_PIXEL_OP_3A_1A(`darken', `', `
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
psubb %mm4, %mm2
|
|
movq %mm2, %mm1', `')
|
|
|
|
MMX_PIXEL_OP_3A_1A(`lighten', `', `
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
paddb %mm4, %mm3
|
|
movq %mm0, %mm1
|
|
pandn %mm3, %mm1
|
|
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1', `')
|
|
|
|
MMX_PIXEL_OP_3A_1A(`screen', `
|
|
movq .mult_shift, %mm7
|
|
pxor %mm6, %mm6',`
|
|
|
|
pcmpeqb %mm4, %mm4
|
|
psubb %mm2, %mm4
|
|
pcmpeqb %mm5, %mm5
|
|
psubb %mm3, %mm5
|
|
|
|
movq %mm4, %mm1
|
|
punpcklbw %mm6, %mm1
|
|
movq %mm5, %mm3
|
|
punpcklbw %mm6, %mm3
|
|
pmullw %mm3, %mm1
|
|
paddw %mm7, %mm1
|
|
movq %mm1, %mm3
|
|
psrlw $ 8, %mm3
|
|
paddw %mm3, %mm1
|
|
psrlw $ 8, %mm1
|
|
|
|
movq %mm4, %mm2
|
|
punpckhbw %mm6, %mm2
|
|
movq %mm5, %mm3
|
|
punpckhbw %mm6, %mm3
|
|
pmullw %mm3, %mm2
|
|
paddw %mm7, %mm2
|
|
movq %mm2, %mm3
|
|
psrlw $ 8, %mm3
|
|
paddw %mm3, %mm2
|
|
psrlw $ 8, %mm2
|
|
|
|
packuswb %mm2, %mm1
|
|
|
|
pcmpeqb %mm3, %mm3
|
|
psubb %mm1, %mm3
|
|
|
|
movq %mm0, %mm1
|
|
pandn %mm3, %mm1
|
|
|
|
movq %mm2, %mm4
|
|
psubusb %mm5, %mm2
|
|
paddb %mm2, %mm5
|
|
pcmpeqb %mm3, %mm3
|
|
psubb %mm5, %mm3
|
|
|
|
pand %mm0, %mm3
|
|
por %mm3, %mm1', `')
|
|
|
|
.lower_ff: .int 0x00FF00FF, 0x00FF00FF
|
|
|
|
MMX_PIXEL_OP_3A_1A(`overlay', `
|
|
movq .mult_shift, %mm7
|
|
pxor %mm6, %mm6 ',
|
|
`call op_overlay', `')
|
|
|
|
op_overlay:
|
|
movq %mm2, %mm1
|
|
punpcklbw %mm6, %mm1
|
|
movq %mm3, %mm5
|
|
punpcklbw %mm6, %mm5
|
|
pmullw %mm5, %mm1
|
|
paddw %mm7, %mm1
|
|
movq %mm1, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm1
|
|
psrlw $ 8, %mm1
|
|
|
|
pcmpeqb %mm4, %mm4
|
|
psubb %mm2, %mm4
|
|
punpcklbw %mm6, %mm4
|
|
pcmpeqb %mm5, %mm5
|
|
psubb %mm3, %mm5
|
|
punpcklbw %mm6, %mm5
|
|
pmullw %mm5, %mm4
|
|
paddw %mm7, %mm4
|
|
movq %mm4, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm4
|
|
psrlw $ 8, %mm4
|
|
|
|
movq .lower_ff, %mm5
|
|
psubw %mm4, %mm5
|
|
|
|
psubw %mm1, %mm5
|
|
movq %mm2, %mm4
|
|
punpcklbw %mm6, %mm4
|
|
pmullw %mm4, %mm5
|
|
paddw %mm7, %mm5
|
|
movq %mm5, %mm4
|
|
psrlw $ 8, %mm4
|
|
paddw %mm4, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm1, %mm5
|
|
|
|
subl $ 8, %esp
|
|
movq %mm5, (%esp)
|
|
|
|
movq %mm2, %mm1
|
|
punpckhbw %mm6, %mm1
|
|
movq %mm3, %mm5
|
|
punpckhbw %mm6, %mm5
|
|
pmullw %mm5, %mm1
|
|
paddw %mm7, %mm1
|
|
movq %mm1, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm1
|
|
psrlw $ 8, %mm1
|
|
|
|
pcmpeqb %mm4, %mm4
|
|
psubb %mm2, %mm4
|
|
punpckhbw %mm6, %mm4
|
|
pcmpeqb %mm5, %mm5
|
|
psubb %mm3, %mm5
|
|
punpckhbw %mm6, %mm5
|
|
pmullw %mm5, %mm4
|
|
paddw %mm7, %mm4
|
|
movq %mm4, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm5, %mm4
|
|
psrlw $ 8, %mm4
|
|
|
|
movq .lower_ff, %mm5
|
|
psubw %mm4, %mm5
|
|
|
|
psubw %mm1, %mm5
|
|
movq %mm2, %mm4
|
|
punpckhbw %mm6, %mm4
|
|
pmullw %mm4, %mm5
|
|
paddw %mm7, %mm5
|
|
movq %mm5, %mm4
|
|
psrlw $ 8, %mm4
|
|
paddw %mm4, %mm5
|
|
psrlw $ 8, %mm5
|
|
paddw %mm1, %mm5
|
|
|
|
movq (%esp), %mm4
|
|
addl $ 8, %esp
|
|
|
|
packuswb %mm5, %mm4
|
|
movq %mm0, %mm1
|
|
pandn %mm4, %mm1
|
|
|
|
movq %mm2, %mm4
|
|
psubusb %mm3, %mm4
|
|
psubb %mm4, %mm2
|
|
pand %mm0, %mm2
|
|
por %mm2, %mm1
|
|
ret
|