summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/pixops/scale_line_22_33_mmx.S
blob: 6080844c1a39ee5b69e056c386046b9c718a2117 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/*
 * Copyright (C) 2000 Red Hat, Inc
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
	.file	"scale_line_22_33_mmx.S"
	.version	"01.01"
gcc2_compiled.:
.text
	.align 16

#if !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__INTERIX)
	
/* Magic indicating no need for an executable stack */
#if !defined __powerpc64__ && !defined __ia64__
.section .note.GNU-stack;  .previous
#endif
	
.globl _pixops_scale_line_22_33_mmx
	.type	 _pixops_scale_line_22_33_mmx,@function
_pixops_scale_line_22_33_mmx:
	
#else
	
.globl __pixops_scale_line_22_33_mmx
__pixops_scale_line_22_33_mmx:
	
#endif
/*
 * Arguments
 *		
 * weights:	 8(%ebp)
 * p:	        12(%ebp)	%esi
 * q1:	        16(%ebp)	
 * q2:	        20(%ebp)	
 * xstep:       24(%ebp)	
 * p_end:       28(%ebp)
 * xinit:       32(%ebp)
 *	
*/

/*
 * Function call entry
 */
	pushl %ebp
	movl %esp,%ebp
	subl $28,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
/* Locals:	
 * int x                      %ebx
 * int x_scaled             -24(%ebp)
 */

/*
 * Setup
 */
/* Initialize variables */	
	movl 32(%ebp),%ebx
	movl 32(%ebp),%edx
	sarl $16,%edx
	movl 12(%ebp),%esi

	cmpl 28(%ebp),%esi
	jnb  .out

/* For the body of this loop, %mm01, %mm1, %mm2, %mm3 hold the 4 adjoining
 * points we are interpolating between, as:
 *
 *  000000BB00GG00RR
 */	
	
/* Load initial values into %mm1, %mm3 */
	leal (%edx,%edx,2),%edx  # Multiply by 3

	movl 16(%ebp),%edi
	pxor %mm4, %mm4
	movzbl 2(%edi,%edx),%ecx
	shll $16,%ecx
	movzwl (%edi,%edx),%eax
	orl %eax,%ecx
	movd %ecx, %mm1
	punpcklbw %mm4, %mm1

	movl 20(%ebp),%edi
	movzbl 2(%edi,%edx),%ecx
	shll $16,%ecx
	movzwl (%edi,%edx),%eax
	orl %eax,%ecx
	movd %ecx, %mm3
	punpcklbw %mm4, %mm3

	addl $65536,%ebx
	movl %ebx,%edx
	sarl $16,%edx

	jmp .newx
	.p2align 4,,7
.loop:
/* short *pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y
 *                                             16             4                  0xf            2     2
 */
	movl %ebx,%eax
	andl $0xf000,%eax
	shrl $7,%eax

/* At this point, %edi holds weights. Load the 4 weights into %mm4,%mm5,%mm6,%mm7, multiply and
 * accumulate.
 */
	movq (%edi,%eax),%mm4
	pmullw %mm0,%mm4
	movq 8(%edi,%eax),%mm5
	pmullw %mm1,%mm5
	movq 16(%edi,%eax),%mm6
	movq 24(%edi,%eax),%mm7
	pmullw %mm2,%mm6
	pmullw %mm3,%mm7
	paddw %mm4, %mm5
	paddw %mm6, %mm7
	paddw %mm5, %mm7

/* %mm7	holds the accumulated sum. Compute (C + 0x80) / 256
 */
	pxor %mm4, %mm4
	movl $8421504, %eax  # 0x00808080
	movd %eax, %mm6  
	punpcklbw %mm4, %mm6
	paddw %mm6, %mm7
	psrlw $8, %mm7

/* Pack into %eax and store result
 */	
	packuswb %mm7, %mm7
	movd %mm7, %eax
	
	movb %al, (%esi)
	shrl $8, %eax
	movw %ax, 1(%esi)
	addl $3, %esi
		
	cmpl %esi,28(%ebp)
	je   .out

/* x += x_step; */
	addl 24(%ebp),%ebx
/* x_scaled = x >> 16; */
	movl %ebx,%edx
	sarl $16,%edx

	cmpl %edx,-24(%ebp)
	je   .loop

.newx:
	movl %edx,-24(%ebp)
/*
 * Load the two new values into %mm1, %mm3, move old values into %mm0, %mm2
 */
	movq %mm1, %mm0
	movq %mm3, %mm2
	
	leal (%edx,%edx,2),%edx  # Multiply by 3

	movl 16(%ebp),%edi
	movzbl 2(%edi,%edx),%ecx
	shll $16,%ecx
	movzwl (%edi,%edx),%eax
	orl %eax,%ecx
	movd %ecx, %mm1
	punpcklbw %mm4, %mm1

	movl 20(%ebp),%edi
	movzbl 2(%edi,%edx),%ecx
	shll $16,%ecx
	movzwl (%edi,%edx),%eax
	orl %eax,%ecx
	movd %ecx, %mm3
	punpcklbw %mm4, %mm3
	
	movl 8(%ebp),%edi
	
	jmp .loop

.out:
	movl %esi,%eax
	emms
	leal -40(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	movl %ebp,%esp
	popl %ebp
	ret