3d1db631fdf27e0ac16561f718e4ad906153ab82
[x262.git] / common / x86 / mc-a.asm
1 ;*****************************************************************************
2 ;* mc-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Laurent Aimar <fenrir@via.ecp.fr>
8 ;*          Min Chen <chenm001.163.com>
9 ;*
10 ;* This program is free software; you can redistribute it and/or modify
11 ;* it under the terms of the GNU General Public License as published by
12 ;* the Free Software Foundation; either version 2 of the License, or
13 ;* (at your option) any later version.
14 ;*
15 ;* This program is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;* GNU General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU General Public License
21 ;* along with this program; if not, write to the Free Software
22 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23 ;*****************************************************************************
24
25 %include "x86inc.asm"
26
27 SECTION_RODATA
28
29 pw_4:  times 4 dw  4
30 pw_8:  times 4 dw  8
31 pw_32: times 4 dw 32
32 pw_64: times 4 dw 64
33
34 SECTION .text
35
36 ;=============================================================================
37 ; pixel avg
38 ;=============================================================================
39
40 ;-----------------------------------------------------------------------------
41 ; void x264_pixel_avg_4x4_mmxext( uint8_t *dst, int dst_stride,
42 ;                                 uint8_t *src, int src_stride );
43 ;-----------------------------------------------------------------------------
44 %macro AVGH 3
45 %assign function_align 8 ; the whole function fits in 8 bytes, so a larger align just wastes space
46 cglobal x264_pixel_avg_%1x%2_%3
47     mov eax, %2
48     jmp x264_pixel_avg_w%1_%3
49 %assign function_align 16
50 %endmacro
51
52 ;-----------------------------------------------------------------------------
53 ; void x264_pixel_avg_w4_mmxext( uint8_t *dst, int dst_stride,
54 ;                                uint8_t *src, int src_stride,
55 ;                                int height );
56 ;-----------------------------------------------------------------------------
57 %ifdef ARCH_X86_64
58     %define t0 r0
59     %define t1 r1
60     %define t2 r2
61     %define t3 r3
62     %macro AVG_START 1
63         cglobal %1, 4,5
64         .height_loop:
65     %endmacro
66 %else
67     %define t0 r1
68     %define t1 r2
69     %define t2 r3
70     %define t3 r4
71     %macro AVG_START 1
72         cglobal %1, 0,5
73         mov t0, r0m
74         mov t1, r1m
75         mov t2, r2m
76         mov t3, r3m
77         .height_loop:
78     %endmacro
79 %endif
80
81 %macro AVG_END 0
82     sub    eax, 2
83     lea    t2, [t2+t3*2]
84     lea    t0, [t0+t1*2]
85     jg     .height_loop
86     REP_RET
87 %endmacro
88
89 AVG_START x264_pixel_avg_w4_mmxext
90     movd   mm0, [t2]
91     movd   mm1, [t2+t3]
92     pavgb  mm0, [t0]
93     pavgb  mm1, [t0+t1]
94     movd   [t0], mm0
95     movd   [t0+t1], mm1
96 AVG_END
97
98 AVGH 4, 8, mmxext
99 AVGH 4, 4, mmxext
100 AVGH 4, 2, mmxext
101
102 AVG_START x264_pixel_avg_w8_mmxext
103     movq   mm0, [t2]
104     movq   mm1, [t2+t3]
105     pavgb  mm0, [t0]
106     pavgb  mm1, [t0+t1]
107     movq   [t0], mm0
108     movq   [t0+t1], mm1
109 AVG_END
110
111 AVGH 8, 16, mmxext
112 AVGH 8, 8,  mmxext
113 AVGH 8, 4,  mmxext
114
115 AVG_START x264_pixel_avg_w16_mmxext
116     movq   mm0, [t2  ]
117     movq   mm1, [t2+8]
118     movq   mm2, [t2+t3  ]
119     movq   mm3, [t2+t3+8]
120     pavgb  mm0, [t0  ]
121     pavgb  mm1, [t0+8]
122     pavgb  mm2, [t0+t1  ]
123     pavgb  mm3, [t0+t1+8]
124     movq   [t0  ], mm0
125     movq   [t0+8], mm1
126     movq   [t0+t1  ], mm2
127     movq   [t0+t1+8], mm3
128 AVG_END
129
130 AVGH 16, 16, mmxext
131 AVGH 16, 8,  mmxext
132
133 AVG_START x264_pixel_avg_w16_sse2
134     movdqu xmm0, [t2]
135     movdqu xmm1, [t2+t3]
136     pavgb  xmm0, [t0]
137     pavgb  xmm1, [t0+t1]
138     movdqa [t0], xmm0
139     movdqa [t0+t1], xmm1
140 AVG_END
141
142 AVGH 16, 16, sse2
143 AVGH 16, 8,  sse2
144
145
146
147 ;=============================================================================
148 ; pixel avg2
149 ;=============================================================================
150
151 ;-----------------------------------------------------------------------------
152 ; void x264_pixel_avg2_w4_mmxext( uint8_t *dst, int dst_stride,
153 ;                                 uint8_t *src1, int src_stride,
154 ;                                 uint8_t *src2, int height );
155 ;-----------------------------------------------------------------------------
156 %macro AVG2_W8 2
157 cglobal x264_pixel_avg2_w%1_mmxext, 6,7
158     sub    r4, r2
159     lea    r6, [r4+r3]
160 .height_loop:
161     %2     mm0, [r2]
162     %2     mm1, [r2+r3]
163     pavgb  mm0, [r2+r4]
164     pavgb  mm1, [r2+r6]
165     %2     [r0], mm0
166     %2     [r0+r1], mm1
167     sub    r5d, 2
168     lea    r2, [r2+r3*2]
169     lea    r0, [r0+r1*2]
170     jg     .height_loop
171     REP_RET
172 %endmacro
173
174 AVG2_W8 4, movd
175 AVG2_W8 8, movq
176
177 %macro AVG2_W16 2
178 cglobal x264_pixel_avg2_w%1_mmxext, 6,7
179     sub    r4, r2
180     lea    r6, [r4+r3]
181 .height_loop:
182     movq   mm0, [r2]
183     %2     mm1, [r2+8]
184     movq   mm2, [r2+r3]
185     %2     mm3, [r2+r3+8]
186     pavgb  mm0, [r2+r4]
187     pavgb  mm1, [r2+r4+8]
188     pavgb  mm2, [r2+r6]
189     pavgb  mm3, [r2+r6+8]
190     movq   [r0], mm0
191     %2     [r0+8], mm1
192     movq   [r0+r1], mm2
193     %2     [r0+r1+8], mm3
194     lea    r2, [r2+r3*2]
195     lea    r0, [r0+r1*2]
196     sub    r5d, 2
197     jg     .height_loop
198     REP_RET
199 %endmacro
200
201 AVG2_W16 12, movd
202 AVG2_W16 16, movq
203
204 cglobal x264_pixel_avg2_w20_mmxext, 6,7
205     sub    r4, r2
206     lea    r6, [r4+r3]
207 .height_loop:
208     movq   mm0, [r2]
209     movq   mm1, [r2+8]
210     movd   mm2, [r2+16]
211     movq   mm3, [r2+r3]
212     movq   mm4, [r2+r3+8]
213     movd   mm5, [r2+r3+16]
214     pavgb  mm0, [r2+r4]
215     pavgb  mm1, [r2+r4+8]
216     pavgb  mm2, [r2+r4+16]
217     pavgb  mm3, [r2+r6]
218     pavgb  mm4, [r2+r6+8]
219     pavgb  mm5, [r2+r6+16]
220     movq   [r0], mm0
221     movq   [r0+8], mm1
222     movd   [r0+16], mm2
223     movq   [r0+r1], mm3
224     movq   [r0+r1+8], mm4
225     movd   [r0+r1+16], mm5
226     lea    r2, [r2+r3*2]
227     lea    r0, [r0+r1*2]
228     sub    r5d, 2
229     jg     .height_loop
230     REP_RET
231
232 cglobal x264_pixel_avg2_w16_sse2, 6,7
233     sub    r4, r2
234     lea    r6, [r4+r3]
235 .height_loop:
236     movdqu xmm0, [r2]
237     movdqu xmm2, [r2+r3]
238     movdqu xmm1, [r2+r4]
239     movdqu xmm3, [r2+r6]
240     pavgb  xmm0, xmm1
241     pavgb  xmm2, xmm3
242     movdqa [r0], xmm0
243     movdqa [r0+r1], xmm2
244     lea    r2, [r2+r3*2]
245     lea    r0, [r0+r1*2]
246     sub    r5d, 2
247     jg     .height_loop
248     REP_RET
249
250 cglobal x264_pixel_avg2_w20_sse2, 6,7
251     sub    r4, r2
252     lea    r6, [r4+r3]
253 .height_loop:
254     movdqu xmm0, [r2]
255     movdqu xmm2, [r2+r3]
256     movdqu xmm1, [r2+r4]
257     movdqu xmm3, [r2+r6]
258     movd   mm4,  [r2+16]
259     movd   mm5,  [r2+r3+16]
260     pavgb  xmm0, xmm1
261     pavgb  xmm2, xmm3
262     pavgb  mm4,  [r2+r4+16]
263     pavgb  mm5,  [r2+r6+16]
264     movdqa [r0], xmm0
265     movd   [r0+16], mm4
266     movdqa [r0+r1], xmm2
267     movd   [r0+r1+16], mm5
268     lea    r2, [r2+r3*2]
269     lea    r0, [r0+r1*2]
270     sub    r5d, 2
271     jg     .height_loop
272     REP_RET
273
274
275
276 ;=============================================================================
277 ; pixel copy
278 ;=============================================================================
279
280 %macro COPY4 3
281     %1  mm0, [r2]
282     %1  mm1, [r2+r3]
283     %1  mm2, [r2+r3*2]
284     %1  mm3, [r2+%3]
285     %1  [r0],      mm0
286     %1  [r0+r1],   mm1
287     %1  [r0+r1*2], mm2
288     %1  [r0+%2],   mm3
289 %endmacro
290
291 ;-----------------------------------------------------------------------------
292 ; void x264_mc_copy_w4_mmx( uint8_t *dst, int i_dst_stride,
293 ;                           uint8_t *src, int i_src_stride, int i_height )
294 ;-----------------------------------------------------------------------------
295 cglobal x264_mc_copy_w4_mmx, 4,6
296     cmp     r4m, dword 4
297     lea     r5, [r3*3]
298     lea     r4, [r1*3]
299     je .end
300     COPY4 movd, r4, r5
301     lea     r2, [r2+r3*4]
302     lea     r0, [r0+r1*4]
303 .end:
304     COPY4 movd, r4, r5
305     RET
306
307 cglobal x264_mc_copy_w8_mmx, 5,7
308     lea     r6, [r3*3]
309     lea     r5, [r1*3]
310 .height_loop:
311     COPY4 movq, r5, r6
312     lea     r2, [r2+r3*4]
313     lea     r0, [r0+r1*4]
314     sub     r4d, 4
315     jg      .height_loop
316     REP_RET
317
318 cglobal x264_mc_copy_w16_mmx, 5,7
319     lea     r6, [r3*3]
320     lea     r5, [r1*3]
321 .height_loop:
322     movq    mm0, [r2]
323     movq    mm1, [r2+8]
324     movq    mm2, [r2+r3]
325     movq    mm3, [r2+r3+8]
326     movq    mm4, [r2+r3*2]
327     movq    mm5, [r2+r3*2+8]
328     movq    mm6, [r2+r6]
329     movq    mm7, [r2+r6+8]
330     movq    [r0], mm0
331     movq    [r0+8], mm1
332     movq    [r0+r1], mm2
333     movq    [r0+r1+8], mm3
334     movq    [r0+r1*2], mm4
335     movq    [r0+r1*2+8], mm5
336     movq    [r0+r5], mm6
337     movq    [r0+r5+8], mm7
338     lea     r2, [r2+r3*4]
339     lea     r0, [r0+r1*4]
340     sub     r4d, 4
341     jg      .height_loop
342     REP_RET
343
344 cglobal x264_mc_copy_w16_sse2,5,7
345     lea     r6, [r3*3]
346     lea     r5, [r1*3]
347 .height_loop
348     movdqu  xmm0, [r2]
349     movdqu  xmm1, [r2+r3]
350     movdqu  xmm2, [r2+r3*2]
351     movdqu  xmm3, [r2+r6]
352     movdqa  [r0], xmm0
353     movdqa  [r0+r1], xmm1
354     movdqa  [r0+r1*2], xmm2
355     movdqa  [r0+r5], xmm3
356     lea     r2, [r2+r3*4]
357     lea     r0, [r0+r1*4]
358     sub     r4d, 4
359     jg      .height_loop
360     REP_RET
361
362
363
364 ;=============================================================================
365 ; weighted prediction
366 ;=============================================================================
367 ; implicit bipred only:
368 ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
369
370 %macro BIWEIGHT_4P_MMX 2
371     movd      mm0, %1
372     movd      mm1, %2
373     punpcklbw mm0, mm7
374     punpcklbw mm1, mm7
375     pmullw    mm0, mm4
376     pmullw    mm1, mm5
377     paddw     mm0, mm1
378     paddw     mm0, mm6
379     psraw     mm0, 6
380     pmaxsw    mm0, mm7
381     packuswb  mm0, mm0
382     movd      %1,  mm0
383 %endmacro
384
385 %macro BIWEIGHT_START_MMX 1
386 %ifidn r4m, r4d
387     movd    mm4, r4m
388     pshufw  mm4, mm4, 0   ; weight_dst
389 %else
390     pshufw  mm4, r4m, 0
391 %endif
392     picgetgot r4
393     movq    mm5, [pw_64 GLOBAL]
394     psubw   mm5, mm4      ; weight_src
395     movq    mm6, [pw_32 GLOBAL] ; rounding
396     pxor    mm7, mm7
397 %if %1
398 %ifidn r5m, r5d
399     %define t0 r5d
400 %else
401     %define t0 r4d
402     mov  r4d, r5m
403 %endif
404 %endif
405 .height_loop:
406 %endmacro
407
408 ;-----------------------------------------------------------------------------
409 ; int x264_pixel_avg_weight_w16_mmxext( uint8_t *dst, int, uint8_t *src, int, int i_weight, int )
410 ;-----------------------------------------------------------------------------
411 cglobal x264_pixel_avg_weight_w16_mmxext, 4,5
412     BIWEIGHT_START_MMX 1
413     BIWEIGHT_4P_MMX  [r0   ], [r2   ]
414     BIWEIGHT_4P_MMX  [r0+ 4], [r2+ 4]
415     BIWEIGHT_4P_MMX  [r0+ 8], [r2+ 8]
416     BIWEIGHT_4P_MMX  [r0+12], [r2+12]
417     add  r0, r1
418     add  r2, r3
419     dec  t0
420     jg   .height_loop
421     REP_RET
422
423 ;-----------------------------------------------------------------------------
424 ; int x264_pixel_avg_weight_w8_mmxext( uint8_t *, int, uint8_t *, int, int, int )
425 ;-----------------------------------------------------------------------------
426 cglobal x264_pixel_avg_weight_w8_mmxext, 4,5
427     BIWEIGHT_START_MMX 1
428     BIWEIGHT_4P_MMX  [r0  ], [r2  ]
429     BIWEIGHT_4P_MMX  [r0+4], [r2+4]
430     add  r0, r1
431     add  r2, r3
432     dec  t0
433     jg   .height_loop
434     REP_RET
435
436 ;-----------------------------------------------------------------------------
437 ; int x264_pixel_avg_weight_4x4_mmxext( uint8_t *, int, uint8_t *, int, int )
438 ;-----------------------------------------------------------------------------
439 cglobal x264_pixel_avg_weight_4x4_mmxext, 4,4,1
440     BIWEIGHT_START_MMX 0
441     BIWEIGHT_4P_MMX  [r0     ], [r2     ]
442     BIWEIGHT_4P_MMX  [r0+r1  ], [r2+r3  ]
443     BIWEIGHT_4P_MMX  [r0+r1*2], [r2+r3*2]
444     add  r0, r1
445     add  r2, r3
446     BIWEIGHT_4P_MMX  [r0+r1*2], [r2+r3*2]
447     RET
448
449
450
451 ;=============================================================================
452 ; prefetch
453 ;=============================================================================
454 ; FIXME assumes 64 byte cachelines
455
456 ;-----------------------------------------------------------------------------
457 ; void x264_prefetch_fenc_mmxext( uint8_t *pix_y, int stride_y, 
458 ;                                 uint8_t *pix_uv, int stride_uv, int mb_x )
459 ;-----------------------------------------------------------------------------
460 %ifdef ARCH_X86_64
461 cglobal x264_prefetch_fenc_mmxext, 5,5
462     mov    eax, r4d
463     and    eax, 3
464     imul   eax, r1d
465     lea    r0,  [r0+rax*4+64]
466     prefetcht0  [r0]
467     prefetcht0  [r0+r1]
468     lea    r0,  [r0+r1*2]
469     prefetcht0  [r0]
470     prefetcht0  [r0+r1]
471
472     and    r4d, 6
473     imul   r4d, r3d
474     lea    r2,  [r2+r4+64]
475     prefetcht0  [r2]
476     prefetcht0  [r2+r3]
477     ret
478
479 %else
480 cglobal x264_prefetch_fenc_mmxext
481     mov    r2, [esp+20]
482     mov    r1, [esp+8]
483     mov    r0, [esp+4]
484     and    r2, 3
485     imul   r2, r1
486     lea    r0, [r0+r2*4+64]
487     prefetcht0 [r0]
488     prefetcht0 [r0+r1]
489     lea    r0, [r0+r1*2]
490     prefetcht0 [r0]
491     prefetcht0 [r0+r1]
492
493     mov    r2, [esp+20]
494     mov    r1, [esp+16]
495     mov    r0, [esp+12]
496     and    r2, 6
497     imul   r2, r1
498     lea    r0, [r0+r2+64]
499     prefetcht0 [r0]
500     prefetcht0 [r0+r1]
501     ret
502 %endif ; ARCH_X86_64
503
504 ;-----------------------------------------------------------------------------
505 ; void x264_prefetch_ref_mmxext( uint8_t *pix, int stride, int parity )
506 ;-----------------------------------------------------------------------------
507 cglobal x264_prefetch_ref_mmxext, 3,3
508     dec    r2d
509     and    r2d, r1d
510     lea    r0,  [r0+r2*8+64]
511     lea    r2,  [r1*3]
512     prefetcht0  [r0]
513     prefetcht0  [r0+r1]
514     prefetcht0  [r0+r1*2]
515     prefetcht0  [r0+r2]
516     lea    r0,  [r0+r1*4]
517     prefetcht0  [r0]
518     prefetcht0  [r0+r1]
519     prefetcht0  [r0+r1*2]
520     prefetcht0  [r0+r2]
521     ret
522
523
524
525 ;=============================================================================
526 ; chroma MC
527 ;=============================================================================
528
529 ;-----------------------------------------------------------------------------
530 ; void x264_mc_chroma_mmxext( uint8_t *dst, int i_dst_stride,
531 ;                             uint8_t *src, int i_src_stride,
532 ;                             int dx, int dy,
533 ;                             int i_width, int i_height )
534 ;-----------------------------------------------------------------------------
535 cglobal x264_mc_chroma_mmxext, 0,6,1
536 %ifdef ARCH_X86_64
537     %define t0   r10d
538 %else
539     %define t0   r1d
540 %endif
541     movifnidn r2d, r2m
542     movifnidn r3d, r3m
543     movifnidn r4d, r4m
544     movifnidn r5d, r5m
545     mov     eax, r5d
546     mov     t0,  r4d
547     sar     eax, 3
548     sar     t0,  3
549     imul    eax, r3d
550     pxor    mm3, mm3
551     add     eax, t0
552     movsxdifnidn rax, eax
553     add     r2,  rax            ; src += (dx>>3) + (dy>>3) * src_stride
554     and     r4d, 7              ; dx &= 7
555     je      .mc1d
556     and     r5d, 7              ; dy &= 7
557     je      .mc1d
558
559     movd    mm0, r4d
560     movd    mm1, r5d
561     pshufw  mm5, mm0, 0         ; mm5 = dx
562     pshufw  mm6, mm1, 0         ; mm6 = dy
563
564     movq    mm4, [pw_8 GLOBAL]
565     movq    mm0, mm4
566     psubw   mm4, mm5            ; mm4 = 8-dx
567     psubw   mm0, mm6            ; mm0 = 8-dy
568
569     movq    mm7, mm5
570     pmullw  mm5, mm0            ; mm5 = dx*(8-dy) =     cB
571     pmullw  mm7, mm6            ; mm7 = dx*dy =         cD
572     pmullw  mm6, mm4            ; mm6 = (8-dx)*dy =     cC
573     pmullw  mm4, mm0            ; mm4 = (8-dx)*(8-dy) = cA
574
575     mov     r4d, r7m
576 %ifdef ARCH_X86_64
577     mov     r10, r0
578     mov     r11, r2
579 %else
580     mov     r0,  r0m
581     mov     r1,  r1m
582     mov     r5,  r2
583 %endif
584
585 ALIGN 4
586 .height_loop
587
588     movd    mm1, [r2+r3]
589     movd    mm0, [r2]
590     punpcklbw mm1, mm3          ; 00 px1 | 00 px2 | 00 px3 | 00 px4
591     punpcklbw mm0, mm3
592     pmullw  mm1, mm6            ; 2nd line * cC
593     pmullw  mm0, mm4            ; 1st line * cA
594     paddw   mm0, mm1            ; mm0 <- result
595
596     movd    mm2, [r2+1]
597     movd    mm1, [r2+r3+1]
598     punpcklbw mm2, mm3
599     punpcklbw mm1, mm3
600
601     paddw   mm0, [pw_32 GLOBAL]
602
603     pmullw  mm2, mm5            ; line * cB
604     pmullw  mm1, mm7            ; line * cD
605     paddw   mm0, mm2
606     paddw   mm0, mm1
607     psrlw   mm0, 6
608
609     packuswb mm0, mm3           ; 00 00 00 00 px1 px2 px3 px4
610     movd    [r0], mm0
611
612     add     r2,  r3
613     add     r0,  r1             ; i_dst_stride
614     dec     r4d
615     jnz     .height_loop
616
617     sub dword r6m, 8
618     jnz     .finish             ; width != 8 so assume 4
619
620 %ifdef ARCH_X86_64
621     lea     r0, [r10+4]         ; dst
622     lea     r2, [r11+4]         ; src
623 %else
624     mov     r0,  r0m
625     lea     r2, [r5+4]
626     add     r0,  4
627 %endif
628     mov     r4d, r7m            ; i_height
629     jmp     .height_loop
630
631 .finish
632     REP_RET
633
634 ALIGN 4
635 .mc1d
636     mov       eax, r4d
637     or        eax, r5d
638     and       eax, 7
639     cmp       r4d, 0
640     mov       r5d, 1
641     cmove     r5,  r3           ; pel_offset = dx ? 1 : src_stride
642     movd      mm6, eax
643     movq      mm5, [pw_8 GLOBAL]
644     pshufw    mm6, mm6, 0
645     movq      mm7, [pw_4 GLOBAL]
646     psubw     mm5, mm6
647
648     cmp dword r6m, 8
649     movifnidn r0d, r0m
650     movifnidn r1d, r1m
651     mov       r4d, r7m
652     je .height_loop1_w8
653
654 ALIGN 4
655 .height_loop1_w4
656     movd      mm0, [r2+r5]
657     movd      mm1, [r2]
658     punpcklbw mm0, mm3
659     punpcklbw mm1, mm3
660     pmullw    mm0, mm6
661     pmullw    mm1, mm5
662     paddw     mm0, mm7
663     paddw     mm0, mm1
664     psrlw     mm0, 3
665     packuswb  mm0, mm3
666     movd     [r0], mm0
667     add       r2,  r3
668     add       r0,  r1
669     dec       r4d
670     jnz .height_loop1_w4
671     REP_RET
672
673 ALIGN 4
674 .height_loop1_w8
675     movq      mm0, [r2+r5]
676     movq      mm1, [r2]
677     movq      mm2, mm0
678     movq      mm4, mm1
679     punpcklbw mm0, mm3
680     punpcklbw mm1, mm3
681     punpckhbw mm2, mm3
682     punpckhbw mm4, mm3
683     pmullw    mm0, mm6
684     pmullw    mm1, mm5
685     pmullw    mm2, mm6
686     pmullw    mm4, mm5
687     paddw     mm0, mm7
688     paddw     mm2, mm7
689     paddw     mm0, mm1
690     paddw     mm2, mm4
691     psrlw     mm0, 3
692     psrlw     mm2, 3
693     packuswb  mm0, mm2
694     movq     [r0], mm0
695     add       r2,  r3
696     add       r0,  r1
697     dec       r4d
698     jnz .height_loop1_w8
699     REP_RET
700