]> granicus.if.org Git - libvpx/blob - vp8/encoder/x86/quantize_sse2.asm
safety check to avoid divide by 0s
[libvpx] / vp8 / encoder / x86 / quantize_sse2.asm
1 ;
2 ;  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 ;
4 ;  Use of this source code is governed by a BSD-style license and patent
5 ;  grant that can be found in the LICENSE file in the root of the source
6 ;  tree. All contributing project authors may be found in the AUTHORS
7 ;  file in the root of the source tree.
8 ;
9
10
11 %include "vpx_ports/x86_abi_support.asm"
12
13
14 ;int vp8_regular_quantize_b_impl_sse2(short *coeff_ptr, short *zbin_ptr,
15 ;               short *qcoeff_ptr,short *dequant_ptr,
16 ;               const int *default_zig_zag, short *round_ptr,
17 ;               short *quant_ptr, short *dqcoeff_ptr,
18 ;               unsigned short zbin_oq_value,
19 ;               short *zbin_boost_ptr);
20 ;
21 global sym(vp8_regular_quantize_b_impl_sse2)
22 sym(vp8_regular_quantize_b_impl_sse2):
23     push        rbp
24     mov         rbp, rsp
25     SHADOW_ARGS_TO_STACK 10
26     push        rsi
27     push        rdi
28     push        rbx
29     ; end prolog
30
31     ALIGN_STACK 16, rax
32
33     %define abs_minus_zbin_lo 0
34     %define abs_minus_zbin_hi 16
35     %define temp_qcoeff_lo 32
36     %define temp_qcoeff_hi 48
37     %define save_xmm6 64
38     %define save_xmm7 80
39     %define eob 96
40
41     %define vp8_regularquantizeb_stack_size eob + 16
42
43     sub         rsp, vp8_regularquantizeb_stack_size
44
45     movdqa      OWORD PTR[rsp + save_xmm6], xmm6
46     movdqa      OWORD PTR[rsp + save_xmm7], xmm7
47
48     mov         rdx, arg(0)                 ;coeff_ptr
49     mov         eax, arg(8)                 ;zbin_oq_value
50
51     mov         rcx, arg(1)                 ;zbin_ptr
52     movd        xmm7, eax
53
54     movdqa      xmm0, OWORD PTR[rdx]
55     movdqa      xmm4, OWORD PTR[rdx + 16]
56
57     movdqa      xmm1, xmm0
58     movdqa      xmm5, xmm4
59
60     psraw       xmm0, 15                    ;sign of z (aka sz)
61     psraw       xmm4, 15                    ;sign of z (aka sz)
62
63     pxor        xmm1, xmm0
64     pxor        xmm5, xmm4
65
66     movdqa      xmm2, OWORD PTR[rcx]        ;load zbin_ptr
67     movdqa      xmm3, OWORD PTR[rcx + 16]   ;load zbin_ptr
68
69     pshuflw     xmm7, xmm7, 0
70     psubw       xmm1, xmm0                  ;x = abs(z)
71
72     punpcklwd   xmm7, xmm7                  ;duplicated zbin_oq_value
73     psubw       xmm5, xmm4                  ;x = abs(z)
74
75     paddw       xmm2, xmm7
76     paddw       xmm3, xmm7
77
78     psubw       xmm1, xmm2                  ;sub (zbin_ptr + zbin_oq_value)
79     psubw       xmm5, xmm3                  ;sub (zbin_ptr + zbin_oq_value)
80
81     mov         rdi, arg(5)                 ;round_ptr
82     mov         rsi, arg(6)                 ;quant_ptr
83
84     movdqa      OWORD PTR[rsp + abs_minus_zbin_lo], xmm1
85     movdqa      OWORD PTR[rsp + abs_minus_zbin_hi], xmm5
86
87     paddw       xmm1, xmm2                  ;add (zbin_ptr + zbin_oq_value) back
88     paddw       xmm5, xmm3                  ;add (zbin_ptr + zbin_oq_value) back
89
90     movdqa      xmm2, OWORD PTR[rdi]
91     movdqa      xmm3, OWORD PTR[rsi]
92
93     movdqa      xmm6, OWORD PTR[rdi + 16]
94     movdqa      xmm7, OWORD PTR[rsi + 16]
95
96     paddw       xmm1, xmm2
97     paddw       xmm5, xmm6
98
99     pmulhw      xmm1, xmm3
100     pmulhw      xmm5, xmm7
101
102     mov         rsi, arg(2)                 ;qcoeff_ptr
103     pxor        xmm6, xmm6
104
105     pxor        xmm1, xmm0
106     pxor        xmm5, xmm4
107
108     psubw       xmm1, xmm0
109     psubw       xmm5, xmm4
110
111     movdqa      OWORD PTR[rsp + temp_qcoeff_lo], xmm1
112     movdqa      OWORD PTR[rsp + temp_qcoeff_hi], xmm5
113
114     movdqa      OWORD PTR[rsi], xmm6        ;zero qcoeff
115     movdqa      OWORD PTR[rsi + 16], xmm6   ;zero qcoeff
116
117     xor         rax, rax
118     mov         rcx, -1
119
120     mov         [rsp + eob], rcx
121     mov         rsi, arg(9)                 ;zbin_boost_ptr
122
123     mov         rbx, arg(4)                 ;default_zig_zag
124
125 rq_zigzag_loop:
126     movsxd      rcx, DWORD PTR[rbx + rax*4] ;now we have rc
127     movsx       edi, WORD PTR [rsi]         ;*zbin_boost_ptr aka zbin
128     lea         rsi, [rsi + 2]              ;zbin_boost_ptr++
129
130     movsx       edx, WORD PTR[rsp + abs_minus_zbin_lo + rcx *2]
131
132     sub         edx, edi                    ;x - zbin
133     jl          rq_zigzag_1
134
135     mov         rdi, arg(2)                 ;qcoeff_ptr
136
137     movsx       edx, WORD PTR[rsp + temp_qcoeff_lo + rcx *2]
138
139     cmp         edx, 0
140     je          rq_zigzag_1
141
142     mov         WORD PTR[rdi + rcx * 2], dx ;qcoeff_ptr[rc] = temp_qcoeff[rc]
143
144     mov         rsi, arg(9)                 ;zbin_boost_ptr
145     mov         [rsp + eob], rax            ;eob = i
146
147 rq_zigzag_1:
148     movsxd      rcx, DWORD PTR[rbx + rax*4 + 4]
149     movsx       edi, WORD PTR [rsi]         ;*zbin_boost_ptr aka zbin
150     lea         rsi, [rsi + 2]              ;zbin_boost_ptr++
151
152     movsx       edx, WORD PTR[rsp + abs_minus_zbin_lo + rcx *2]
153     lea         rax, [rax + 1]
154
155     sub         edx, edi                    ;x - zbin
156     jl          rq_zigzag_1a
157
158     mov         rdi, arg(2)                 ;qcoeff_ptr
159
160     movsx       edx, WORD PTR[rsp + temp_qcoeff_lo + rcx *2]
161
162     cmp         edx, 0
163     je          rq_zigzag_1a
164
165     mov         WORD PTR[rdi + rcx * 2], dx ;qcoeff_ptr[rc] = temp_qcoeff[rc]
166
167     mov         rsi, arg(9)                 ;zbin_boost_ptr
168     mov         [rsp + eob], rax            ;eob = i
169
170 rq_zigzag_1a:
171     movsxd      rcx, DWORD PTR[rbx + rax*4 + 4]
172     movsx       edi, WORD PTR [rsi]         ;*zbin_boost_ptr aka zbin
173     lea         rsi, [rsi + 2]              ;zbin_boost_ptr++
174
175     movsx       edx, WORD PTR[rsp + abs_minus_zbin_lo + rcx *2]
176     lea         rax, [rax + 1]
177
178     sub         edx, edi                    ;x - zbin
179     jl          rq_zigzag_1b
180
181     mov         rdi, arg(2)                 ;qcoeff_ptr
182
183     movsx       edx, WORD PTR[rsp + temp_qcoeff_lo + rcx *2]
184
185     cmp         edx, 0
186     je          rq_zigzag_1b
187
188     mov         WORD PTR[rdi + rcx * 2], dx ;qcoeff_ptr[rc] = temp_qcoeff[rc]
189
190     mov         rsi, arg(9)                 ;zbin_boost_ptr
191     mov         [rsp + eob], rax            ;eob = i
192
193 rq_zigzag_1b:
194     movsxd      rcx, DWORD PTR[rbx + rax*4 + 4]
195     movsx       edi, WORD PTR [rsi]         ;*zbin_boost_ptr aka zbin
196     lea         rsi, [rsi + 2]              ;zbin_boost_ptr++
197
198     movsx       edx, WORD PTR[rsp + abs_minus_zbin_lo + rcx *2]
199     lea         rax, [rax + 1]
200
201     sub         edx, edi                    ;x - zbin
202     jl          rq_zigzag_1c
203
204     mov         rdi, arg(2)                 ;qcoeff_ptr
205
206     movsx       edx, WORD PTR[rsp + temp_qcoeff_lo + rcx *2]
207
208     cmp         edx, 0
209     je          rq_zigzag_1c
210
211     mov         WORD PTR[rdi + rcx * 2], dx ;qcoeff_ptr[rc] = temp_qcoeff[rc]
212
213     mov         rsi, arg(9)                 ;zbin_boost_ptr
214     mov         [rsp + eob], rax            ;eob = i
215
216 rq_zigzag_1c:
217     lea         rax, [rax + 1]
218
219     cmp         rax, 16
220     jl          rq_zigzag_loop
221
222     mov         rdi, arg(2)                 ;qcoeff_ptr
223     mov         rcx, arg(3)                 ;dequant_ptr
224     mov         rsi, arg(7)                 ;dqcoeff_ptr
225
226     movdqa      xmm2, OWORD PTR[rdi]
227     movdqa      xmm3, OWORD PTR[rdi + 16]
228
229     movdqa      xmm0, OWORD PTR[rcx]
230     movdqa      xmm1, OWORD PTR[rcx + 16]
231
232     pmullw      xmm0, xmm2
233     pmullw      xmm1, xmm3
234
235     movdqa      OWORD PTR[rsi], xmm0        ;store dqcoeff
236     movdqa      OWORD PTR[rsi + 16], xmm1   ;store dqcoeff
237
238     mov         rax, [rsp + eob]
239
240     movdqa      xmm6, OWORD PTR[rsp + save_xmm6]
241     movdqa      xmm7, OWORD PTR[rsp + save_xmm7]
242
243     add         rax, 1
244
245     add         rsp, vp8_regularquantizeb_stack_size
246     pop         rsp
247
248     ; begin epilog
249     pop         rbx
250     pop         rdi
251     pop         rsi
252     UNSHADOW_ARGS
253     pop         rbp
254     ret
255
256
257 ;int vp8_fast_quantize_b_impl_sse2(short *coeff_ptr,
258 ;                           short *qcoeff_ptr,short *dequant_ptr,
259 ;                           short *scan_mask, short *round_ptr,
260 ;                           short *quant_ptr, short *dqcoeff_ptr);
261 global sym(vp8_fast_quantize_b_impl_ssse2)
262 sym(vp8_fast_quantize_b_impl_ssse2):
263     push        rbp
264     mov         rbp, rsp
265     SHADOW_ARGS_TO_STACK 7
266     push        rsi
267     push        rdi
268     push        rbx
269     ; end prolog
270
271     ALIGN_STACK 16, rax
272
273     %define save_xmm6  0
274     %define save_xmm7 16
275
276     %define vp8_fastquantizeb_stack_size save_xmm7 + 16
277
278     sub         rsp, vp8_fastquantizeb_stack_size
279
280     movdqa      XMMWORD PTR[rsp + save_xmm6], xmm6
281     movdqa      XMMWORD PTR[rsp + save_xmm7], xmm7
282
283     mov         rdx, arg(0)                 ;coeff_ptr
284     mov         rcx, arg(2)                 ;dequant_ptr
285     mov         rax, arg(3)                 ;scan_mask
286     mov         rdi, arg(4)                 ;round_ptr
287     mov         rsi, arg(5)                 ;quant_ptr
288
289     movdqa      xmm0, XMMWORD PTR[rdx]
290     movdqa      xmm4, XMMWORD PTR[rdx + 16]
291
292     movdqa      xmm6, XMMWORD PTR[rdi]      ;round lo
293     movdqa      xmm7, XMMWORD PTR[rdi + 16] ;round hi
294
295     movdqa      xmm1, xmm0
296     movdqa      xmm5, xmm4
297
298     psraw       xmm0, 15                    ;sign of z (aka sz)
299     psraw       xmm4, 15                    ;sign of z (aka sz)
300
301     pxor        xmm1, xmm0
302     pxor        xmm5, xmm4
303     psubw       xmm1, xmm0                  ;x = abs(z)
304     psubw       xmm5, xmm4                  ;x = abs(z)
305
306     paddw       xmm1, xmm6
307     paddw       xmm5, xmm7
308
309     pmulhw      xmm1, XMMWORD PTR[rsi]
310     pmulhw      xmm5, XMMWORD PTR[rsi + 16]
311
312     mov         rdi, arg(1)                 ;qcoeff_ptr
313     mov         rsi, arg(6)                 ;dqcoeff_ptr
314
315     movdqa      xmm6, XMMWORD PTR[rcx]
316     movdqa      xmm7, XMMWORD PTR[rcx + 16]
317
318     pxor        xmm1, xmm0
319     pxor        xmm5, xmm4
320     psubw       xmm1, xmm0
321     psubw       xmm5, xmm4
322
323     movdqa      XMMWORD PTR[rdi], xmm1
324     movdqa      XMMWORD PTR[rdi + 16], xmm5
325
326     pmullw      xmm6, xmm1
327     pmullw      xmm7, xmm5
328
329     movdqa      xmm2, XMMWORD PTR[rax]
330     movdqa      xmm3, XMMWORD PTR[rax+16];
331
332     pxor        xmm4, xmm4            ;clear all bits
333     pcmpeqw     xmm1, xmm4
334     pcmpeqw     xmm5, xmm4
335
336     pcmpeqw     xmm4, xmm4            ;set all bits
337     pxor        xmm1, xmm4
338     pxor        xmm5, xmm4
339
340     psrlw       xmm1, 15
341     psrlw       xmm5, 15
342
343     pmaddwd     xmm1, xmm2
344     pmaddwd     xmm5, xmm3
345
346     movq        xmm2, xmm1
347     movq        xmm3, xmm5
348
349     psrldq      xmm1, 8
350     psrldq      xmm5, 8
351
352     paddd       xmm1, xmm5
353     paddd       xmm2, xmm3
354
355     paddd       xmm1, xmm2
356     movq        xmm5, xmm1
357
358     psrldq      xmm1, 4
359     paddd       xmm5, xmm1
360
361     movq        rcx,  xmm5
362     and         rcx,  0xffff
363
364     xor         rdx,  rdx
365     sub         rdx,  rcx
366
367     bsr         rax,  rcx
368     inc         rax
369
370     sar         rdx,  31
371     and         rax,  rdx
372
373     movdqa      XMMWORD PTR[rsi], xmm6        ;store dqcoeff
374     movdqa      XMMWORD PTR[rsi + 16], xmm7   ;store dqcoeff
375
376     movdqa      xmm6, XMMWORD PTR[rsp + save_xmm6]
377     movdqa      xmm7, XMMWORD PTR[rsp + save_xmm7]
378
379     add         rsp, vp8_fastquantizeb_stack_size
380     pop         rsp
381
382     ; begin epilog
383     pop         rbx
384     pop         rdi
385     pop         rsi
386     UNSHADOW_ARGS
387     pop         rbp
388     ret