2420c4016ae9ecafc88fa85dffb9cc8166b5a831
[melted] / src / modules / gtk2 / scale_line_22_yuv_mmx.S
1         .file   "scale_line_22_yuv_mmx.S"
2         .version        "01.01"
3
4 .extern printf
5
6 gcc2_compiled.:
7 .data
8 MSG: .ascii "scale_line_22_yuv_mmx: %d %d\n"
9
10 .text
11         .align 16
12
13 #if !defined(__MINGW32__) && !defined(__CYGWIN__)       
14         
15 .globl pixops_scale_line_22_yuv_mmx
16         .type    pixops_scale_line_22_yuv_mmx,@function
17 pixops_scale_line_22_yuv_mmx:
18         
19 #else
20         
21 .globl _pixops_scale_line_22_yuv_mmx
22 _pixops_scale_line_22_yuv_mmx:
23         
24 #endif
25 /*
26  * Arguments
27  *              
28  * weights:      8(%ebp)
29  * p (dest):    12(%ebp)        %esi
30  * q1 (src0):   16(%ebp)        
31  * q2 (src1):   20(%ebp)        
32  * xstep:       24(%ebp)        
33  * p_end:       28(%ebp)
34  * xinit:       32(%ebp)
35  * destx:       36(%ebp)
36  *
37 */
38
39 /*
40  * Function call entry
41  */
42         pushl %ebp
43         movl %esp,%ebp
44         subl $28,%esp
45         pushl %edi
46         pushl %esi
47         pushl %ebx
48 /* Locals:
49  * int x                      %ebx
50  * int x_scaled             -24(%ebp)
51  * int dest_x               36(%ebp)
52  */
53
54 /*
55  * Setup
56  */
57 /* Initialize variables */
58         movl 36(%ebp),%eax # destx
59         movl %eax,36(%ebp)
60         movl 32(%ebp),%ebx # x
61         movl 12(%ebp),%esi # dest
62
63         cmpl 28(%ebp),%esi # dest == dest_end ?
64         jnb  .out
65
66         addl $65536, %ebx
67         .p2align 4,,7
68         pxor %mm4, %mm4
69
70 /* For the body of this loop, %mm0, %mm1, %mm2, %mm3 hold the 4 adjoining
71  * points we are interpolating between, as:
72  *
73  *  00UV00Y200UV00Y1
74  */
75
76 .loop:
77
78 /*
79  * Load current values from pixel 1
80  */
81         movl %ebx, %edx          # x_scaled = x ...
82         sarl $15, %edx           # >> 16
83         andl $-2, %edx           # x_scaled *= channels
84         movl %edx, -24(%ebp)     # save x_scaled
85
86         movl 16(%ebp), %edi      # get src0
87         movzbl (%edi,%edx), %ecx # current y = src0[ x_scaled ]
88
89         andl $-4, %edx           # x_aligned
90
91         movl 36(%ebp), %eax      # uv_index = dest_x ...
92         andl $1, %eax            # ( dest_x & 1 ) ...
93         sall $1, %eax            # << 1
94         addl %eax, %edx          # x_aligned += uv_index
95         movl %edx, -20(%ebp)     # save x_aligned
96
97         movzbl 1(%edi,%edx), %eax # uv = src0[ x_aligned + 1 ]
98         shll $8, %eax           # position uv
99         orl %eax, %ecx           # store uv
100
101         movd %ecx, %mm0          # move to mmx0
102         punpcklbw %mm4, %mm0
103
104         /* this is the next x, not simply x_scaled again */
105         movl %ebx, %edx          # x_scaled = x ...
106         addl 24(%ebp), %edx      # + x_step
107         sarl $15, %edx           # >> 16
108         andl $-2, %edx           # x_scaled *= channels
109         movl %edx, -16(%ebp)     # save next x_scaled
110
111         movzbl (%edi,%edx), %ecx # next y = src0[ x_scaled ]
112         orl %eax, %ecx           # store uv
113
114         movd %ecx, %mm1          # move to mmx1
115         punpcklbw %mm4, %mm1
116
117         movl 20(%ebp), %edi      # get src1
118         movl -24(%ebp), %edx     # restore x_scaled
119         movzbl (%edi,%edx), %ecx # current y = src1[ x_scaled ]
120
121         movl -20(%ebp), %edx     # restore x_aligned
122         movzbl 1(%edi,%edx), %eax # uv = src1[ x_aligned + 1 ]
123         shll $8, %eax            # position uv
124         orl %eax, %ecx           # store uv
125
126         movd %ecx, %mm2          # move to mmx2
127         punpcklbw %mm4, %mm2
128
129         movl -16(%ebp), %edx     # restore next x_scaled
130         movzbl (%edi,%edx), %ecx # next y = src0[ x_scaled ]
131         orl %eax, %ecx           # store uv
132
133         movd %ecx, %mm3          # move to mmx3
134         punpcklbw %mm4, %mm3
135
136 /* short *pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y
137  *                                             16             4                  0xf            2     2
138  */
139         movl 8(%ebp), %edi       # get weights pointer
140         movl %ebx, %eax
141         andl $0xf000, %eax
142         shrl $7, %eax
143
144 /* At this point, %edi holds weights. Load the 4 weights into 
145  * %mm4,%mm5,%mm6,%mm7, multiply and accumulate.
146  */
147         movq (%edi,%eax), %mm4
148         pmullw %mm0, %mm4
149         movq 8(%edi,%eax), %mm5
150         pmullw %mm1, %mm5
151         movq 16(%edi,%eax), %mm6
152         pmullw %mm2,%mm6
153         movq 24(%edi,%eax), %mm7
154         pmullw %mm3,%mm7
155
156         paddw %mm4, %mm5
157         paddw %mm6, %mm7
158         paddw %mm5, %mm7
159
160 /* %mm7 holds the accumulated sum. Compute (C + 0x80) / 256
161  */
162         pxor %mm4, %mm4
163         movl $0x80808080, %eax
164         movd %eax, %mm6
165         punpcklbw %mm4, %mm6
166         paddw %mm6, %mm7
167         psrlw $8, %mm7
168
169 /* Pack into %eax and store result
170  */
171         packuswb %mm7, %mm7
172         movd %mm7, %eax
173
174         movb %al, 0(%esi)        # dest[ 0 ] = y
175         shrl $8, %eax
176         movb %al, 1(%esi)        # dest[ 1 ] = uv
177
178         addl $2, %esi            # dest += 2
179
180         cmpl %esi,28(%ebp)       # if dest == dest_end
181         je   .out                # then exit
182
183         addl 24(%ebp), %ebx      # x += x_step
184         addl $1, 36(%ebp)        # dest_x++
185
186         jmp .loop
187
188 .out:
189         movl %esi,%eax
190         emms
191         leal -40(%ebp),%esp
192         popl %ebx
193         popl %esi
194         popl %edi
195         movl %ebp,%esp
196         popl %ebp
197         ret