]> git.sesse.net Git - x264/blob - common/amd64/mc-a.asm
Windows 64bit asm.
[x264] / common / amd64 / mc-a.asm
1 ;*****************************************************************************
2 ;* mc.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003 x264 project
5 ;* $Id: mc.asm,v 1.3 2004/06/18 01:59:58 chenm001 Exp $
6 ;*
7 ;* Authors: Min Chen <chenm001.163.com> (converted to nasm)
8 ;*          Laurent Aimar <fenrir@via.ecp.fr> (init algorithm)
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 ;*****************************************************************************
26 ;*                                                                           *
27 ;*  Revision history:                                                        *
28 ;*                                                                           *
29 ;*  2004.05.17 portab mc_copy_w4/8/16 (CM)                                   *
30 ;*                                                                           *
31 ;*****************************************************************************
32
33 BITS 64
34
35 ;=============================================================================
36 ; Macros and other preprocessor constants
37 ;=============================================================================
38
39 %include "amd64inc.asm"
40
41 ;=============================================================================
42 ; Constants
43 ;=============================================================================
44
45 SECTION .rodata
46
47 ALIGN 16
48 pw_4:  times 4 dw  4
49 pw_8:  times 4 dw  8
50 pw_32: times 4 dw 32
51 pw_64: times 4 dw 64
52
53 ;=============================================================================
54 ; Code
55 ;=============================================================================
56
57 SECTION .text
58
59 cglobal x264_pixel_avg_w4_mmxext
60 cglobal x264_pixel_avg_w8_mmxext
61 cglobal x264_pixel_avg_w16_mmxext
62 cglobal x264_pixel_avg_w16_sse2
63
64 cglobal x264_pixel_avg_weight_4x4_mmxext
65 cglobal x264_pixel_avg_weight_w8_mmxext
66 cglobal x264_pixel_avg_weight_w16_mmxext
67
68 cglobal x264_mc_copy_w4_mmxext
69 cglobal x264_mc_copy_w8_mmxext
70 cglobal x264_mc_copy_w16_mmxext
71 cglobal x264_mc_copy_w16_sse2
72
73 cglobal x264_mc_chroma_sse
74
75 ;=============================================================================
76 ; pixel avg
77 ;=============================================================================
78
79 ALIGN 16
80 ;-----------------------------------------------------------------------------
81 ; void x264_pixel_avg_w4_mmxext( uint8_t *dst,  int i_dst_stride,
82 ;                                uint8_t *src1, int i_src1_stride,
83 ;                                uint8_t *src2, int i_src2_stride,
84 ;                                int i_height );
85 ;-----------------------------------------------------------------------------
86 x264_pixel_avg_w4_mmxext:
87     mov         r10, parm5q         ; src2
88     movsxd      r11, parm6d         ; i_src2_stride
89     movsxd      rax, parm7d         ; i_height
90
91 ALIGN 4
92 .height_loop    
93     movd        mm0, [parm3q]
94     pavgb       mm0, [r10]
95     movd        mm1, [parm3q+parm4q]
96     pavgb       mm1, [r10+r11]
97     movd        [parm1q], mm0
98     movd        [parm1q+parm2q], mm1
99     dec         rax
100     dec         rax
101     lea         parm3q, [parm3q+parm4q*2]
102     lea         r10, [r10+r11*2]
103     lea         parm1q, [parm1q+parm2q*2]
104     jne         .height_loop
105
106     ret
107
108                           
109
110 ALIGN 16
111 ;-----------------------------------------------------------------------------
112 ; void x264_pixel_avg_w8_mmxext( uint8_t *dst,  int i_dst_stride,
113 ;                                uint8_t *src1, int i_src1_stride,
114 ;                                uint8_t *src2, int i_src2_stride,
115 ;                                int i_height );
116 ;-----------------------------------------------------------------------------
117 x264_pixel_avg_w8_mmxext:
118
119     mov         r10, parm5q         ; src2
120     movsxd      r11, parm6d         ; i_src2_stride
121     movsxd      rax, parm7d         ; i_height
122
123 ALIGN 4
124 .height_loop    
125     movq        mm0, [parm3q]
126     pavgb       mm0, [r10]
127     movq        [parm1q], mm0
128     dec         rax
129     lea         parm3q, [parm3q+parm4q]
130     lea         r10, [r10+r11]
131     lea         parm1q, [parm1q+parm2q]
132     jne         .height_loop
133
134     ret
135
136 ALIGN 16
137 ;-----------------------------------------------------------------------------
138 ; void x264_pixel_avg_w16_mmxext( uint8_t *dst,  int i_dst_stride,
139 ;                                 uint8_t *src1, int i_src1_stride,
140 ;                                 uint8_t *src2, int i_src2_stride,
141 ;                                 int i_height );
142 ;-----------------------------------------------------------------------------
143 x264_pixel_avg_w16_mmxext:
144     mov         r10, parm5q         ; src2
145     movsxd      r11, parm6d         ; i_src2_stride
146     movsxd      rax, parm7d         ; i_height
147
148 ALIGN 4
149 .height_loop    
150     movq        mm0, [parm3q  ]
151     movq        mm1, [parm3q+8]
152     pavgb       mm0, [r10  ]
153     pavgb       mm1, [r10+8]
154     movq        [parm1q  ], mm0
155     movq        [parm1q+8], mm1
156     dec         rax
157     lea         parm3q, [parm3q+parm4q]
158     lea         r10, [r10+r11]
159     lea         parm1q, [parm1q+parm2q]
160     jne         .height_loop
161
162     ret
163
164 ALIGN 16
165 ;-----------------------------------------------------------------------------
166 ; void x264_pixel_avg_w16_sse2( uint8_t *dst,  int i_dst_stride,
167 ;                               uint8_t *src1, int i_src1_stride,
168 ;                               uint8_t *src2, int i_src2_stride,
169 ;                               int i_height );
170 ;-----------------------------------------------------------------------------
171 x264_pixel_avg_w16_sse2:
172     mov         r10, parm5q         ; src2
173     movsxd      r11, parm6d         ; i_src2_stride
174     movsxd      rax, parm7d         ; i_height
175
176 ALIGN 4
177 .height_loop    
178     movdqu      xmm0, [parm3q]
179     pavgb       xmm0, [r10]
180     movdqu      [parm1q], xmm0
181
182     dec         rax
183     lea         parm3q, [parm3q+parm4q]
184     lea         r10, [r10+r11]
185     lea         parm1q, [parm1q+parm2q]
186     jne         .height_loop
187
188     ret
189
190
191
192 ;=============================================================================
193 ; weighted prediction
194 ;=============================================================================
195 ; implicit bipred only:
196 ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
197
198 %macro BIWEIGHT_4P_MMX 2
199     movd      mm0, %1
200     movd      mm1, %2
201     punpcklbw mm0, mm7
202     punpcklbw mm1, mm7
203     pmullw    mm0, mm4
204     pmullw    mm1, mm5
205     paddw     mm0, mm1
206     paddw     mm0, mm6
207     psraw     mm0, 6
208     pmaxsw    mm0, mm7
209     packuswb  mm0, mm0
210     movd      %1,  mm0
211 %endmacro
212
213 %macro BIWEIGHT_START_MMX 0
214 ;   mov     rdi, rdi      ; dst
215 ;   movsxd  rsi, esi      ; i_dst
216 ;   mov     rdx, rdx      ; src
217 ;   movsxd  rcx, ecx      ; i_src
218 ;   movsxd  r8,  r8d      ; i_weight_dst
219 ;   movsxd  r9,  r9d      ; i_height
220     mov     r11d, parm6d  ; i_height
221
222     movd    mm4, parm5d
223     pshufw  mm4, mm4, 0   ; weight_dst
224     movq    mm5, [pw_64 GLOBAL]
225     psubw   mm5, mm4      ; weight_src
226     movq    mm6, [pw_32 GLOBAL] ; rounding
227     pxor    mm7, mm7
228
229     ALIGN 4
230     .height_loop
231 %endmacro
232
233 ALIGN 16
234 ;-----------------------------------------------------------------------------
235 ;   int x264_pixel_avg_weight_w16_mmxext( uint8_t *dst, int, uint8_t *src, int, int i_weight, int )
236 ;-----------------------------------------------------------------------------
237 x264_pixel_avg_weight_w16_mmxext:
238     BIWEIGHT_START_MMX
239
240     BIWEIGHT_4P_MMX  [parm1q   ], [parm3q   ]
241     BIWEIGHT_4P_MMX  [parm1q+ 4], [parm3q+ 4]
242     BIWEIGHT_4P_MMX  [parm1q+ 8], [parm3q+ 8]
243     BIWEIGHT_4P_MMX  [parm1q+12], [parm3q+12]
244
245     add  parm1q, parm2q
246     add  parm3q, parm4q
247     dec  r11d
248     jnz  .height_loop
249     ret
250
251 ALIGN 16
252 ;-----------------------------------------------------------------------------
253 ;   int x264_pixel_avg_weight_w8_mmxext( uint8_t *, int, uint8_t *, int, int, int )
254 ;-----------------------------------------------------------------------------
255 x264_pixel_avg_weight_w8_mmxext:
256     BIWEIGHT_START_MMX
257
258     BIWEIGHT_4P_MMX  [parm1q         ], [parm3q         ]
259     BIWEIGHT_4P_MMX  [parm1q+4       ], [parm3q+4       ]
260     BIWEIGHT_4P_MMX  [parm1q+parm2q  ], [parm3q+parm4q  ]
261     BIWEIGHT_4P_MMX  [parm1q+parm2q+4], [parm3q+parm4q+4]
262
263     lea  parm1q, [parm1q+parm2q*2]
264     lea  parm3q, [parm3q+parm4q*2]
265     sub  r11d, byte 2
266     jnz  .height_loop
267     ret
268
269 ALIGN 16
270 ;-----------------------------------------------------------------------------
271 ;   int x264_pixel_avg_weight_4x4_mmxext( uint8_t *, int, uint8_t *, int, int )
272 ;-----------------------------------------------------------------------------
273 x264_pixel_avg_weight_4x4_mmxext:
274     BIWEIGHT_START_MMX
275     BIWEIGHT_4P_MMX  [parm1q         ], [parm3q         ]
276     BIWEIGHT_4P_MMX  [parm1q+parm2q  ], [parm3q+parm4q  ]
277     BIWEIGHT_4P_MMX  [parm1q+parm2q*2], [parm3q+parm4q*2]
278     add  parm1q, parm2q
279     add  parm3q, parm4q
280     BIWEIGHT_4P_MMX  [parm1q+parm2q*2], [parm3q+parm4q*2]
281     ret
282
283
284
285 ;=============================================================================
286 ; pixel copy
287 ;=============================================================================
288
289 ALIGN 16
290 ;-----------------------------------------------------------------------------
291 ;  void x264_mc_copy_w4_mmxext( uint8_t *src, int i_src_stride,
292 ;                               uint8_t *dst, int i_dst_stride, int i_height )
293 ;-----------------------------------------------------------------------------
294 x264_mc_copy_w4_mmxext:
295     mov     eax, parm5d         ; i_height
296     
297 ALIGN 4
298 .height_loop
299     mov     r10d, [parm1q]
300     mov     r11d, [parm1q+parm2q]
301     mov     [parm3q], r10d
302     mov     [parm3q+parm4q], r11d
303     lea     parm1q, [parm1q+parm2q*2]
304     lea     parm3q, [parm3q+parm4q*2]
305     dec     eax
306     dec     eax
307     jne     .height_loop
308
309     ret
310
311 ALIGN 16
312 ;-----------------------------------------------------------------------------
313 ;   void x264_mc_copy_w8_mmxext( uint8_t *src, int i_src_stride,
314 ;                                uint8_t *dst, int i_dst_stride, int i_height )
315 ;-----------------------------------------------------------------------------
316 x264_mc_copy_w8_mmxext:
317     mov     eax, parm5d         ; i_height
318
319     lea     r10, [parm2q+parm2q*2] ; 3 * i_src_stride
320     lea     r11, [parm4q+parm4q*2] ; 3 * i_dst_stride
321
322 ALIGN 4
323 .height_loop
324     movq    mm0, [parm1q]
325     movq    mm1, [parm1q+parm2q]
326     movq    mm2, [parm1q+parm2q*2]
327     movq    mm3, [parm1q+r10]
328     movq    [parm3q], mm0
329     movq    [parm3q+parm4q], mm1
330     movq    [parm3q+parm4q*2], mm2
331     movq    [parm3q+r11], mm3
332     lea     parm1q, [parm1q+parm2q*4]
333     lea     parm3q, [parm3q+parm4q*4]
334     
335     sub     eax, byte 4
336     jnz     .height_loop
337
338     ret
339
340 ALIGN 16
341 ;-----------------------------------------------------------------------------
342 ;   void x264_mc_copy_w16_mmxext( uint8_t *src, int i_src_stride,
343 ;                                 uint8_t *dst, int i_dst_stride, int i_height )
344 ;-----------------------------------------------------------------------------
345 x264_mc_copy_w16_mmxext:
346     mov     eax, parm5d         ; i_height
347     
348     lea     r10, [parm2q+parm2q*2] ; 3 * i_src_stride
349     lea     r11, [parm4q+parm4q*2] ; 3 * i_dst_stride
350
351 ALIGN 4
352 .height_loop
353     movq    mm0, [parm1q]
354     movq    mm1, [parm1q+8]
355     movq    mm2, [parm1q+parm2q]
356     movq    mm3, [parm1q+parm2q+8]
357     movq    mm4, [parm1q+parm2q*2]
358     movq    mm5, [parm1q+parm2q*2+8]
359     movq    mm6, [parm1q+r10]
360     movq    mm7, [parm1q+r10+8]
361     movq    [parm3q], mm0
362     movq    [parm3q+8], mm1
363     movq    [parm3q+parm4q], mm2
364     movq    [parm3q+parm4q+8], mm3
365     movq    [parm3q+parm4q*2], mm4
366     movq    [parm3q+parm4q*2+8], mm5
367     movq    [parm3q+r11], mm6
368     movq    [parm3q+r11+8], mm7
369     lea     parm1q, [parm1q+parm2q*4]
370     lea     parm3q, [parm3q+parm4q*4]
371     sub     eax, byte 4
372     jnz     .height_loop
373     
374     ret
375
376
377 ALIGN 16
378 ;-----------------------------------------------------------------------------
379 ;   void x264_mc_copy_w16_sse2( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, int i_height )
380 ;-----------------------------------------------------------------------------
381 x264_mc_copy_w16_sse2:
382     mov     eax, parm5d         ; i_height
383
384 ALIGN 4
385 .height_loop
386     movdqu  xmm0, [parm1q]
387     movdqu  xmm1, [parm1q+parm2q]
388     movdqu  [parm3q], xmm0
389     movdqu  [parm3q+parm4q], xmm1
390     dec     eax
391     dec     eax
392     lea     parm1q, [parm1q+parm2q*2]
393     lea     parm3q, [parm3q+parm4q*2]
394     jnz     .height_loop
395     
396     ret
397
398
399
400 ;=============================================================================
401 ; chroma MC
402 ;=============================================================================
403
404 ALIGN 16
405 ;-----------------------------------------------------------------------------
406 ;   void x264_mc_chroma_sse( uint8_t *src, int i_src_stride,
407 ;                               uint8_t *dst, int i_dst_stride,
408 ;                               int dx, int dy,
409 ;                               int i_height, int i_width )
410 ;-----------------------------------------------------------------------------
411
412 x264_mc_chroma_sse:
413     movd    mm0, parm5d
414     movd    mm1, parm6d
415
416     pxor    mm3, mm3
417
418     pshufw  mm5, mm0, 0    ; mm5 - dx
419     pshufw  mm6, mm1, 0    ; mm6 - dy
420
421     movq    mm4, [pw_8 GLOBAL]
422     movq    mm0, mm4
423
424     psubw   mm4, mm5            ; mm4 - 8-dx
425     psubw   mm0, mm6            ; mm0 - 8-dy
426
427     movq    mm7, mm5
428     pmullw  mm5, mm0            ; mm5 = dx*(8-dy) =     cB
429     pmullw  mm7, mm6            ; mm7 = dx*dy =         cD
430     pmullw  mm6, mm4            ; mm6 = (8-dx)*dy =     cC
431     pmullw  mm4, mm0            ; mm4 = (8-dx)*(8-dy) = cA
432
433     mov     rax, parm1q
434     mov     r10, parm3q
435     mov     r11d, parm7d
436
437 ALIGN 4
438 .height_loop
439
440     movd    mm1, [rax+parm2q]
441     movd    mm0, [rax]
442     punpcklbw mm1, mm3          ; 00 px1 | 00 px2 | 00 px3 | 00 px4
443     punpcklbw mm0, mm3
444     pmullw  mm1, mm6            ; 2nd line * cC
445     pmullw  mm0, mm4            ; 1st line * cA
446
447     paddw   mm0, mm1            ; mm0 <- result
448
449     movd    mm2, [rax+1]
450     movd    mm1, [rax+parm2q+1]
451     punpcklbw mm2, mm3
452     punpcklbw mm1, mm3
453
454     paddw   mm0, [pw_32 GLOBAL]
455
456     pmullw  mm2, mm5            ; line * cB
457     pmullw  mm1, mm7            ; line * cD
458     paddw   mm0, mm2
459     paddw   mm0, mm1
460
461     psrlw   mm0, 6
462     packuswb mm0, mm3           ; 00 00 00 00 px1 px2 px3 px4
463     movd    [r10], mm0
464
465     add     rax, parm2q
466     add     r10, parm4q         ; i_dst_stride
467
468     dec     r11d
469     jnz     .height_loop
470
471     mov     eax, parm8d         ; i_width
472     sub     eax, 8
473     jnz     .finish             ; width != 8 so assume 4
474
475     mov     parm8d, eax         ; i_width
476     mov     r10, parm3q         ; dst
477     mov     rax, parm1q         ; src
478     mov     r11d, parm7d        ; i_height
479     add     r10, 4
480     add     rax, 4
481     jmp    .height_loop
482
483 .finish
484     ret