[cvs] / xvidcore / src / quant / x86_asm / quantize4_xmm.asm Repository:
ViewVC logotype

Diff of /xvidcore/src/quant/x86_asm/quantize4_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Thu Dec 19 00:40:55 2002 UTC revision 1.1.2.1, Thu Dec 19 00:40:55 2002 UTC
# Line 0  Line 1 
1    ;/******************************************************************************
2    ; *                                                                            *
3    ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *
4    ; *                                                                            *
5    ; *  XviD is an implementation of a part of one or more MPEG-4 Video tools     *
6    ; *  as specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
7    ; *  software module in hardware or software products are advised that its     *
8    ; *  use may infringe existing patents or copyrights, and any such use         *
9    ; *  would be at such party's own risk.  The original developer of this        *
10    ; *  software module and his/her company, and subsequent editors and their     *
11    ; *  companies, will have no liability for use of this software or             *
12    ; *  modifications or derivatives thereof.                                     *
13    ; *                                                                            *
14    ; *  XviD is free software; you can redistribute it and/or modify it           *
15    ; *  under the terms of the GNU General Public License as published by         *
16    ; *  the Free Software Foundation; either version 2 of the License, or         *
17    ; *  (at your option) any later version.                                       *
18    ; *                                                                            *
19    ; *  XviD is distributed in the hope that it will be useful, but               *
20    ; *  WITHOUT ANY WARRANTY; without even the implied warranty of                *
21    ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
22    ; *  GNU General Public License for more details.                              *
23    ; *                                                                            *
24    ; *  You should have received a copy of the GNU General Public License         *
25    ; *  along with this program; if not, write to the Free Software               *
26    ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *
27    ; *                                                                            *
28    ; ******************************************************************************/
29    ;
30    ;/******************************************************************************
31    ; *   quant4 bugs have been fixed: (a) overflow bug for matrix elements            *
32    ; *   equal to 1 or 2 is fixed by substituting pmulhw with pmulhuw (iSSE)          *
33    ; *   and using multiplier 0ffffh instead of 10001h (for matrix element = 1;   *
34    ; *   in that case, 1 is added before multiplying, that additional 1 comes         *
35    ; *   from intra_matrix1; (b) rounding error for large coefficients and matrix *
36    ; *   elements is fixed by two-step approach: first approximation (rounded         *
37    ; *   down) is found as usual; the result is multiplied by the matrix element  *
38    ; *   and mismatch is used to calculate the correction.                                            *
39    ; ******************************************************************************/
40    ;
41    ; _3dne functions are compatible with iSSE, but are optimized specifically for
42    ; K7 pipelines
43    ;
44    ;------------------------------------------------------------------------------
45    ; 09.12.2002  Athlon optimizations contributed by Jaan Kalda
46    ;------------------------------------------------------------------------------
47    
48    
49    ; data/text alignment
50    %define ALIGN 8
51    %define SATURATE
52    
53    bits 32
54    
55    section .data data  align=8
56    
57    %macro cglobal 1
58            %ifdef PREFIX
59                    global _%1
60                    %define %1 _%1
61            %else
62                    global %1
63            %endif
64    %endmacro
65    
66    %macro cextern 1
67            %ifdef PREFIX
68                    extern _%1
69                    %define %1 _%1
70            %else
71                    extern %1
72            %endif
73    %endmacro
74    align 8
75    mmzero dd 0,0
76    
77    mmx_one times 4 dw       1
78    
79    ;===========================================================================
80    ;
81    ; divide by 2Q table
82    ;
83    ;===========================================================================
84    
85    align ALIGN
86    mmx_divs            ;i>2
87    %assign i 1
88    %rep 31
89            times 4 dw  ((1 << 15) / i + 1)
90            %assign i i+1
91    %endrep
92    
93    align ALIGN
94    mmx_div            ;i>2
95    %assign i 1
96    %rep 31
97            times 4 dw  ((1 << 16) / i + 1)
98            %assign i i+1
99    %endrep
100    
101    
102    ;===========================================================================
103    ;
104    ; intra matrix
105    ;
106    ;===========================================================================
107    
108    %macro FIXX 1
109    dw (1 << 16) / (%1) + 1
110    %endmacro
111    
112    cextern intra_matrix_fixl
113    cextern intra_matrix_fix
114    cextern intra_matrix1
115    cextern intra_matrix
116    
117    ;===========================================================================
118    ;
119    ; inter matrix
120    ;
121    ;===========================================================================
122    
123    cextern inter_matrix1
124    cextern inter_matrix
125    cextern inter_matrix_fix
126    cextern inter_matrix_fixl
127    
128    
129    %define VM18P 3
130    %define VM18Q 4
131    %define nop4 DB 08Dh,074h,026h,0
132    %define nop3 add esp,byte 0
133    %define nop2 mov esp,esp
134    %define nop7 db 08dh,02ch,02dh,0,0,0,0
135    %define nop6 add ebp,dword 0
136    ;===========================================================================
137    ;
138    ; quantd table
139    ;
140    ;===========================================================================
141    
142    
143    quantd
144    %assign i 1
145    %rep 31
146            times 4 dw  (((VM18P*i) + (VM18Q/2)) / VM18Q)
147            %assign i i+1
148    %endrep
149    
150    ;===========================================================================
151    ;
152    ; multiple by 2Q table
153    ;
154    ;===========================================================================
155    
156    
157    mmx_mul_quant
158    %assign i 1
159    %rep 31
160            times 4 dw  i
161            %assign i i+1
162    %endrep
163    
164    ;===========================================================================
165    ;
166    ; saturation limits
167    ;
168    ;===========================================================================
169    
170    align 16
171    
172    mmx_32767_minus_2047                            times 4 dw (32767-2047)
173    mmx_32768_minus_2048                            times 4 dw (32768-2048)
174    mmx_2047 times 4 dw 2047
175    mmx_minus_2048 times 4 dw (-2048)
176    zero times 4 dw 0
177    
178    int_div
179    dd 0
180    %assign i 1
181    %rep 255
182            dd  (1 << 17) / ( i) + 1
183            %assign i i+1
184    %endrep
185    
186    section .text
187    
188    ;===========================================================================
189    ;
190    ; void quant_intra4_xmm(int16_t * coeff,
191    ;                                       const int16_t const * data,
192    ;                                       const uint32_t quant,
193    ;                                       const uint32_t dcscalar);
194    ;
195    ;===========================================================================
196    
197    align ALIGN
198    cglobal quant4_intra_xmm
199    quant4_intra_xmm
200    
201                    mov     eax, [esp  + 8]         ; data
202                    mov     ecx, [esp  + 12]        ; quant
203                    mov     edx, [esp  + 4]         ; coeff
204                    push    esi
205                    push    edi
206                    push    ebx
207                    nop
208                    mov edi,mmzero
209                    mov esi,-14
210                    pxor mm0,mm0
211                    pxor mm3,mm3
212                    cmp     ecx,byte 1
213                    je      near .q1loop
214                    cmp     ecx,byte 19
215                    jg near .lloop
216                    nop6
217    
218    
219    align ALIGN
220    .loop
221                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
222                    psubw   mm0,mm1 ;-mm1
223                    movq    mm4, [eax + 8*esi + 120]        ;
224                    psubw   mm3,mm4 ;-mm4
225                    pmaxsw  mm0,mm1 ;|src|
226                    pmaxsw  mm3,mm4
227                    nop2
228                    psraw   mm1,15 ;sign src
229                    psraw   mm4,15
230                    psllw   mm0, 4                  ; level << 4
231                    psllw   mm3, 4                  ;
232                    paddw   mm0, [intra_matrix1 + 8*esi+112]
233                    paddw   mm3, [intra_matrix1 + 8*esi+120]
234                    movq    mm5,[intra_matrix_fixl + 8*esi+112]
235                    movq    mm7,[intra_matrix_fixl + 8*esi+120]
236                    pmulhuw mm5,mm0
237                    pmulhuw mm7,mm3
238                    mov esp,esp
239                    movq   mm2,[intra_matrix + 8*esi+112]
240                    movq   mm6,[intra_matrix + 8*esi+120]
241                    pmullw mm2,mm5
242                    pmullw mm6,mm7
243                    psubw mm0,mm2
244                    psubw mm3,mm6
245                    nop4
246                    movq mm2,[quantd + ecx * 8 - 8]
247                    movq mm6,[mmx_divs + ecx * 8 - 8]
248                    paddw mm5,mm2
249                    paddw mm7,mm2
250                    mov esp,esp
251                    pmulhuw mm0,[intra_matrix_fix + 8*esi+112]
252                    pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
253                    paddw mm5,mm0
254                    paddw mm7,mm3
255                    movq mm0,[edi]
256                    movq mm3,[edi]
257                    pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
258                    pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)
259                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
260                    pxor    mm7, mm4                ;
261                    psubw   mm5, mm1                ; undisplace
262                    psubw   mm7, mm4                ;
263                    movq    [edx + 8*esi+112], mm5
264                    movq    [edx + 8*esi +120], mm7
265                    add esi,byte 2
266                    jng     near .loop
267    .done
268                    ; caclulate  data[0] // (int32_t)dcscalar)
269    
270    
271            mov     esi, [esp + 12 + 16]    ; dcscalar
272            movsx   ecx, word [eax]
273            mov             edi,ecx
274            mov     edx,[esp + 12 + 16]
275            shr     edx, 1                  ; ebx = dcscalar /2
276            sar             edi,31 ;cdq is vectorpath
277            xor             edx,edi ; ebx = eax V -eax -1
278            sub             ecx,edi
279            add             ecx,edx
280            mov     edx,[dword esp + 12 + 4]
281            mov     esi,[int_div+4*esi]
282            imul    ecx,esi
283            sar     ecx,17
284    ;               idiv    cx                      ; ecx = edi:ecx / dcscalar
285    
286                    mov ebx,[esp]
287                    mov edi,[esp+4]
288                    mov esi,[esp+8]
289                    add esp,byte 12
290                    mov     [edx], cx               ; coeff[0] = ax
291    
292                    ret
293    
294    align ALIGN
295    .q1loop
296                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
297                    psubw   mm0,mm1 ;-mm1
298                    movq    mm4, [eax + 8*esi+120]  ;
299                    psubw   mm3,mm4 ;-mm4
300                    pmaxsw  mm0,mm1 ;|src|
301                    pmaxsw  mm3,mm4
302                    nop2
303                    psraw   mm1,15 ;sign src
304                    psraw   mm4,15
305                    psllw   mm0, 4                                                          ; level << 4
306                    psllw   mm3, 4
307                    paddw   mm0, [intra_matrix1 + 8*esi+112]        ;mm0 is to be divided
308                    paddw   mm3, [intra_matrix1 + 8*esi+120]        ; intra1 contains fix for division by 1
309                    movq    mm5,[intra_matrix_fixl + 8*esi+112] ;with rounding down
310                    movq    mm7,[intra_matrix_fixl + 8*esi+120]
311                    pmulhuw mm5,mm0
312                    pmulhuw mm7,mm3                                                         ;mm7: first approx of division
313                    mov esp,esp
314                    movq   mm2,[intra_matrix + 8*esi+112]
315                    movq   mm6,[intra_matrix + 8*esi+120]           ; divs for q<=16
316                    pmullw mm2,mm5                                                          ;test value <= original
317                    pmullw mm6,mm7
318                    psubw mm0,mm2                                                           ;mismatch
319                    psubw mm3,mm6
320                    nop4
321                    movq mm2,[quantd + ecx * 8 - 8]
322                    paddw mm5,mm2                                                           ;first approx with quantd
323                    paddw mm7,mm2
324                    mov esp,esp
325                    pmulhuw mm0,[intra_matrix_fix + 8*esi+112]  ;correction
326                    pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
327                    paddw mm5,mm0                                                           ;final result with quantd
328                    paddw mm7,mm3
329                    movq mm0,[edi]
330                    movq mm3,[edi]
331                    mov esp,esp
332                    psrlw   mm5, 1                  ;  (level + quantd) /2  (quant = 1)
333                    psrlw   mm7, 1
334                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
335                    pxor    mm7, mm4                ;
336                    psubw   mm5, mm1                ; undisplace
337                    psubw   mm7, mm4                ;
338                    movq    [edx + 8*esi+112], mm5
339                    movq    [edx + 8*esi +120], mm7
340                    add esi,byte 2
341                    jng     near .q1loop
342                    jmp     near .done
343    
344    align 8
345    .lloop
346                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
347                    psubw   mm0,mm1 ;-mm1
348                    movq    mm4, [eax + 8*esi+120]  ;
349                    psubw   mm3,mm4 ;-mm4
350                    pmaxsw  mm0,mm1 ;|src|
351                    pmaxsw  mm3,mm4
352                    nop2
353                    psraw   mm1,15 ;sign src
354                    psraw   mm4,15
355                    psllw   mm0, 4                  ; level << 4
356                    psllw   mm3, 4                  ;
357                    paddw   mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
358                    paddw   mm3, [intra_matrix1 + 8*esi+120]
359                    movq    mm5,[intra_matrix_fixl + 8*esi+112]
360                    movq    mm7,[intra_matrix_fixl + 8*esi+120]
361                    pmulhuw mm5,mm0
362                    pmulhuw mm7,mm3  ;mm7: first approx of division
363                    mov esp,esp
364                    movq   mm2,[intra_matrix + 8*esi+112]
365                    movq   mm6,[intra_matrix + 8*esi+120]
366                    pmullw mm2,mm5 ;test value <= original
367                    pmullw mm6,mm7
368                    psubw mm0,mm2 ;mismatch
369                    psubw mm3,mm6
370                    nop4
371                    movq mm2,[quantd + ecx * 8 - 8]
372                    movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
373                    paddw mm5,mm2 ;first approx with quantd
374                    paddw mm7,mm2
375                    mov esp,esp
376                    pmulhuw mm0,[intra_matrix_fix + 8*esi+112] ;correction
377                    pmulhuw mm3,[intra_matrix_fix + 8*esi+120]
378                    paddw mm5,mm0 ;final result with quantd
379                    paddw mm7,mm3
380                    movq mm0,[edi]
381                    movq mm3,[edi]
382                    mov esp,esp
383                    pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
384                    pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)
385                    psrlw   mm5, 1                  ; (level + quantd) / (2*quant)
386                    psrlw   mm7, 1
387                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
388                    pxor    mm7, mm4                ;
389                    psubw   mm5, mm1                ; undisplace
390                    psubw   mm7, mm4                ;
391                    movq    [edx + 8*esi+112], mm5
392                    movq    [edx + 8*esi +120], mm7
393                    add esi,byte 2
394                    jng     near .lloop
395                    jmp     near .done
396    
397    ;===========================================================================
398    ;
399    ; uint32_t quant4_inter_xmm(int16_t * coeff,
400    ;                                       const int16_t const * data,
401    ;                                       const uint32_t quant);
402    ;
403    ;===========================================================================
404    
405    align ALIGN
406    cglobal quant4_inter_xmm
407                    quant4_inter_xmm
408    
409                    mov     eax, [esp  + 8]         ; data
410                    mov     ecx, [esp  + 12]        ; quant
411                    mov     edx, [esp  + 4]         ; coeff
412                    push    esi
413                    push    edi
414                    push    ebx
415                    nop
416                    mov edi,mmzero
417                    mov esi,-14
418                    mov ebx,esp
419                    sub esp,byte 24
420                    lea ebx,[esp+8]
421                    and ebx,byte -8 ;align 8
422                    pxor mm0,mm0
423                    pxor mm3,mm3
424                    movq [byte ebx],mm0
425                    db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
426                    cmp     ecx,byte 1
427                    je      near .q1loop
428                    cmp     ecx,byte 19
429                    jg near .lloop
430                    nop
431    
432    
433    align ALIGN
434    .loop
435                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
436                    psubw   mm0,mm1 ;-mm1
437                    movq    mm4, [eax + 8*esi + 120]        ;
438                    psubw   mm3,mm4 ;-mm4
439                    pmaxsw  mm0,mm1 ;|src|
440                    pmaxsw  mm3,mm4
441                    nop2
442                    psraw   mm1,15 ;sign src
443                    psraw   mm4,15
444                    psllw   mm0, 4                  ; level << 4
445                    psllw   mm3, 4                  ;
446                    paddw   mm0, [inter_matrix1 + 8*esi+112]
447                    paddw   mm3, [inter_matrix1 + 8*esi+120]
448                    movq    mm5,[inter_matrix_fixl + 8*esi+112]
449                    movq    mm7,[inter_matrix_fixl + 8*esi+120]
450                    pmulhuw mm5,mm0
451                    pmulhuw mm7,mm3
452                    mov esp,esp
453                    movq   mm2,[inter_matrix + 8*esi+112]
454                    movq   mm6,[inter_matrix + 8*esi+120]
455                    pmullw mm2,mm5
456                    pmullw mm6,mm7
457                    psubw mm0,mm2
458                    psubw mm3,mm6
459                    movq mm2,[byte ebx]
460                    movq mm6,[mmx_divs + ecx * 8 - 8]
461                    pmulhuw mm0,[inter_matrix_fix + 8*esi+112]
462                    pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
463                    paddw mm2,[ebx+8]   ;sum
464                    paddw mm5,mm0
465                    paddw mm7,mm3
466                    movq mm0,[edi]
467                    movq mm3,[edi]
468                    pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
469                    pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)
470                    add esi,byte 2
471                    paddw   mm2,mm5 ;sum += x1
472                    movq    [ebx],mm7 ;store x2
473                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
474                    pxor    mm7, mm4                ;
475                    psubw   mm5, mm1                ; undisplace
476                    psubw   mm7, mm4                ;
477                    db 0Fh, 7Fh, 54h, 23h, 08 ;movq         [ebx+8],mm2 ;store sum
478                    movq    [edx + 8*esi+112-16], mm5
479                    movq    [edx + 8*esi +120-16], mm7
480                    jng     near .loop
481    .done
482                    ; caclulate  data[0] // (int32_t)dcscalar)
483    
484                    paddw mm2,[ebx]
485                    mov ebx,[esp+24]
486                    mov edi,[esp+4+24]
487                    mov esi,[esp+8+24]
488                    add esp,byte 12+24
489                    pmaddwd mm2, [mmx_one]
490                    punpckldq mm0,mm2 ;get low dw to mm0:high
491                    paddd mm0,mm2
492                    punpckhdq mm0,mm0 ;get result to low
493                    movd    eax, mm0
494                    ret
495    
496    align ALIGN
497    .q1loop
498                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
499                    psubw   mm0,mm1 ;-mm1
500                    movq    mm4, [eax + 8*esi+120]  ;
501                    psubw   mm3,mm4 ;-mm4
502                    pmaxsw  mm0,mm1 ;|src|
503                    pmaxsw  mm3,mm4
504                    nop2
505                    psraw   mm1,15 ;sign src
506                    psraw   mm4,15
507                    psllw   mm0, 4                                                          ; level << 4
508                    psllw   mm3, 4
509                    paddw   mm0, [inter_matrix1 + 8*esi+112]        ;mm0 is to be divided
510                    paddw   mm3, [inter_matrix1 + 8*esi+120]        ; inter1 contains fix for division by 1
511                    movq    mm5,[inter_matrix_fixl + 8*esi+112] ;with rounding down
512                    movq    mm7,[inter_matrix_fixl + 8*esi+120]
513                    pmulhuw mm5,mm0
514                    pmulhuw mm7,mm3                                                         ;mm7: first approx of division
515                    mov esp,esp
516                    movq   mm2,[inter_matrix + 8*esi+112]
517                    movq   mm6,[inter_matrix + 8*esi+120]           ; divs for q<=16
518                    pmullw mm2,mm5                                                          ;test value <= original
519                    pmullw mm6,mm7
520                    psubw mm0,mm2                                                           ;mismatch
521                    psubw mm3,mm6
522                    movq mm2,[byte ebx]
523                    pmulhuw mm0,[inter_matrix_fix + 8*esi+112]  ;correction
524                    pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
525                    paddw mm2,[ebx+8]   ;sum
526                    paddw mm5,mm0                                                           ;final result
527                    paddw mm7,mm3
528                    movq mm0,[edi]
529                    movq mm3,[edi]
530                    psrlw   mm5, 1                  ;  (level ) /2  (quant = 1)
531                    psrlw   mm7, 1
532                    add esi,byte 2
533                    paddw   mm2,mm5 ;sum += x1
534                    movq    [ebx],mm7 ;store x2
535                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
536                    pxor    mm7, mm4                ;
537                    psubw   mm5, mm1                ; undisplace
538                    psubw   mm7, mm4                ;
539                    movq    [ebx+8],mm2 ;store sum
540                    movq    [edx + 8*esi+112-16], mm5
541                    movq    [edx + 8*esi +120-16], mm7
542                    jng     near .q1loop
543                    jmp     near .done
544    
545    align 8
546    .lloop
547                    movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
548                    psubw   mm0,mm1 ;-mm1
549                    movq    mm4, [eax + 8*esi+120]  ;
550                    psubw   mm3,mm4 ;-mm4
551                    pmaxsw  mm0,mm1 ;|src|
552                    pmaxsw  mm3,mm4
553                    nop2
554                    psraw   mm1,15 ;sign src
555                    psraw   mm4,15
556                    psllw   mm0, 4                  ; level << 4
557                    psllw   mm3, 4                  ;
558                    paddw   mm0, [inter_matrix1 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
559                    paddw   mm3, [inter_matrix1 + 8*esi+120]
560                    movq    mm5,[inter_matrix_fixl + 8*esi+112]
561                    movq    mm7,[inter_matrix_fixl + 8*esi+120]
562                    pmulhuw mm5,mm0
563                    pmulhuw mm7,mm3  ;mm7: first approx of division
564                    mov esp,esp
565                    movq   mm2,[inter_matrix + 8*esi+112]
566                    movq   mm6,[inter_matrix + 8*esi+120]
567                    pmullw mm2,mm5 ;test value <= original
568                    pmullw mm6,mm7
569                    psubw mm0,mm2 ;mismatch
570                    psubw mm3,mm6
571                    movq mm2,[byte ebx]
572                    movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
573                    pmulhuw mm0,[inter_matrix_fix + 8*esi+112] ;correction
574                    pmulhuw mm3,[inter_matrix_fix + 8*esi+120]
575                    paddw mm5,mm0 ;final result
576                    paddw mm7,mm3
577                    movq mm0,[edi]
578                    movq mm3,[edi]
579                    mov esp,esp
580                    pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
581                    pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)
582                    add esi,byte 2
583                    paddw   mm2,mm5 ;sum += x1
584                    movq    [ebx],mm7 ;store x2
585                    psrlw   mm5, 1                  ; (level ) / (2*quant)
586                    psrlw   mm7, 1
587                    pxor    mm5, mm1                ; mm0 *= sign(mm0)
588                    pxor    mm7, mm4                ;
589                    psubw   mm5, mm1                ; undisplace
590                    psubw   mm7, mm4                ;
591                    db 0Fh, 7Fh, 54h, 23h, 08 ;movq         [ebx+8],mm2 ;store sum
592                    movq    [edx + 8*esi+112-16], mm5
593                    movq    [edx + 8*esi +120-16], mm7
594                    jng     near .lloop
595                    jmp     near .done
596    
597    
598    ;===========================================================================
599    ;
600    ; void dequant4_intra_mmx(int16_t *data,
601    ;                    const int16_t const *coeff,
602    ;                    const uint32_t quant,
603    ;                    const uint32_t dcscalar);
604    ;
605    ;===========================================================================
606    
607      ;   Note: in order to saturate 'easily', we pre-shift the quantifier
608      ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
609      ; build a saturating mask. It is non-zero only when an overflow occured.
610      ; We thus avoid packing/unpacking toward double-word.
611      ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
612      ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
613      ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
614      ; and quant in [1..31].
615      ;
616      ;********************************************************************
617    %macro DEQUANT4INTRAMMX 1
618      movq mm1, [byte ecx+ 16 * %1]   ; mm0 = c  = coeff[i]
619      movq mm4, [ecx+ 16 * %1 +8]; mm3 = c' = coeff[i+1]
620      psubw mm0,mm1
621      psubw mm3,mm4
622      pmaxsw mm0,mm1
623      pmaxsw mm3,mm4
624      psraw mm1,15
625      psraw mm4,15
626    %if %1
627      movq mm2,[eax+8]   ;preshifted quant
628      movq mm7,[eax+8]
629    %endif
630      pmullw mm2,  [intra_matrix + 16 * %1 ]  ; matrix[i]*quant
631      pmullw mm7,  [intra_matrix + 16 * %1 +8]  ; matrix[i+1]*quant
632      movq mm5,mm0
633      movq mm6,mm3
634      pmulhw mm0, mm2   ; high of coeff*(matrix*quant)
635      pmulhw mm3, mm7   ; high of coeff*(matrix*quant)
636      pmullw mm2, mm5   ; low  of coeff*(matrix*quant)
637      pmullw mm7, mm6   ; low  of coeff*(matrix*quant)
638      pcmpgtw mm0, [eax]
639      pcmpgtw mm3, [eax]
640      paddusw mm2, mm0
641      paddusw mm7, mm3
642      psrlw mm2, 5
643      psrlw mm7, 5
644      pxor mm2, mm1  ; start negating back
645      pxor mm7, mm4  ; start negating back
646      psubusw mm1, mm0
647      psubusw mm4, mm3
648      movq mm0,[eax] ;zero
649      movq mm3,[eax] ;zero
650      psubw mm2, mm1 ; finish negating back
651      psubw mm7, mm4 ; finish negating back
652      movq [byte edx + 16 * %1], mm2   ; data[i]
653      movq [edx + 16 * %1  +8], mm7   ; data[i+1]
654    %endmacro
655    
656    align 16
657    cglobal dequant4_intra_3dne
658    dequant4_intra_3dne:
659    
660      mov eax, [esp+12] ; quant
661      mov ecx, [esp+8]  ; coeff
662      movq mm7, [mmx_mul_quant  + eax*8 - 8]
663      psllw mm7, 2   ; << 2. See comment.
664      mov edx, [esp+4]  ; data
665            push ebx
666      movsx ebx,word [ecx]
667      pxor mm0, mm0
668      pxor mm3, mm3
669      push esi
670      lea eax,[esp-28]
671      sub esp,byte 32
672      and eax,byte -8 ;points to qword aligned space on stack
673      movq [eax],mm0
674      movq [eax+8],mm7
675      imul ebx,[esp+16+8+32]    ; dcscalar
676      movq mm2,mm7
677    
678    
679    align 4
680            DEQUANT4INTRAMMX 0
681            mov esi,-2048
682            nop
683            cmp ebx,esi
684            DEQUANT4INTRAMMX 1
685            cmovl ebx,esi
686            neg esi
687            sub esi,byte 1 ;2047
688            DEQUANT4INTRAMMX 2
689            cmp ebx,esi
690            cmovg ebx,esi
691            lea ebp,[byte ebp]
692            DEQUANT4INTRAMMX 3
693        mov esi,[esp+32]
694              mov [byte edx], bx
695              mov ebx,[esp+32+4]
696            DEQUANT4INTRAMMX 4
697            DEQUANT4INTRAMMX 5
698            DEQUANT4INTRAMMX 6
699            DEQUANT4INTRAMMX 7
700              add esp,byte 32+8
701    
702     ret
703    
704    ;===========================================================================
705    ;
706    ; void dequant4_inter_3dne(int16_t * data,
707    ;                    const int16_t * const coeff,
708    ;                    const uint32_t quant);
709    ;
710    ;===========================================================================
711    
712        ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
713        ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
714        ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
715        ; It's mixed with the extraction of the absolute value.
716    
717    align 16
718    cglobal dequant4_inter_3dne
719    dequant4_inter_3dne:
720    
721      mov    edx, [esp+ 4]        ; data
722      mov    ecx, [esp+ 8]        ; coeff
723      mov    eax, [esp+12]        ; quant
724      movq mm7, [mmx_mul_quant  + eax*8 - 8]
725      mov eax, -14
726      paddw mm7, mm7    ; << 1
727      pxor mm6, mm6 ; mismatch sum
728      push esi
729      mov esi,mmzero
730      pxor mm1,mm1
731      pxor mm3,mm3
732      nop
733      nop4
734    
735    align 16
736    .loop
737      movq mm0, [ecx+8*eax + 7*16   ]   ; mm0 = coeff[i]
738      pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
739      movq mm2, [ecx+8*eax + 7*16 +8]   ; mm2 = coeff[i+1]
740      pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
741      paddsw mm0, mm1   ; c += sgn(c)
742      paddsw mm2, mm3   ; c += sgn(c')
743      paddw mm0, mm0    ; c *= 2
744      paddw mm2, mm2    ; c'*= 2
745    
746      movq mm4, [esi]
747      movq mm5, [esi]
748      psubw mm4, mm0    ; -c
749      psubw mm5, mm2    ; -c'
750    
751      psraw mm4, 16     ; mm4 = sgn(-c)
752      psraw mm5, 16     ; mm5 = sgn(-c')
753      psubsw mm0, mm4   ; c  -= sgn(-c)
754      psubsw mm2, mm5   ; c' -= sgn(-c')
755      pxor mm0, mm1     ; finish changing sign if needed
756      pxor mm2, mm3     ; finish changing sign if needed
757    
758        ; we're short on register, here. Poor pairing...
759    
760      movq mm4, mm7     ; (matrix*quant)
761      nop
762      pmullw mm4,  [inter_matrix + 8*eax + 7*16]
763      movq mm5, mm4
764      pmulhw mm5, mm0   ; high of c*(matrix*quant)
765      pmullw mm0, mm4   ; low  of c*(matrix*quant)
766    
767      movq mm4, mm7     ; (matrix*quant)
768      pmullw mm4,  [inter_matrix + 8*eax + 7*16 + 8]
769      add eax,byte 2
770    
771      pcmpgtw mm5, [esi]
772      paddusw mm0, mm5
773      psrlw mm0, 5
774      pxor mm0, mm1     ; start restoring sign
775      psubusw mm1, mm5
776    
777      movq mm5, mm4
778      pmulhw mm5, mm2   ; high of c*(matrix*quant)
779      pmullw mm2, mm4   ; low  of c*(matrix*quant)
780      psubw mm0, mm1    ; finish restoring sign
781    
782      pcmpgtw mm5, [esi]
783      paddusw mm2, mm5
784      psrlw mm2, 5
785      pxor mm2, mm3    ; start restoring sign
786      psubusw mm3, mm5
787      psubw mm2, mm3   ; finish restoring sign
788      movq mm1, [esi]
789      movq mm3, [byte esi]
790      pxor mm6, mm0     ; mismatch control
791      movq [edx + 8*eax + 7*16 -2*8   ], mm0   ; data[i]
792      pxor mm6, mm2     ; mismatch control
793      movq [edx + 8*eax + 7*16 -2*8 +8], mm2   ; data[i+1]
794    
795      jng  .loop
796      nop
797    
798      ; mismatch control
799    
800      pshufw mm0,mm6,01010101b
801      pshufw mm1,mm6,10101010b
802      pshufw mm2,mm6,11111111b
803      pxor mm6, mm0
804      pxor mm1, mm2
805      pxor mm6, mm1
806      movd eax, mm6
807      and eax,byte 1
808      xor eax,byte 1
809      mov esi,[esp]
810      add esp,byte 4
811      xor word [edx + 2*63], ax
812    
813      ret
814    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.1

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4