]> git.sesse.net Git - x264/blob - common/x86/mc-a2.asm
memcpy_aligned_sse2
[x264] / common / x86 / mc-a2.asm
1 ;*****************************************************************************
2 ;* mc-a2.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Mathieu Monnier <manao@melix.net>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22 ;*****************************************************************************
23
24 %include "x86inc.asm"
25
26 SECTION_RODATA
27
28 pw_1:  times 4 dw 1
29 pw_16: times 4 dw 16
30 pw_32: times 4 dw 32
31
32 SECTION .text
33
34 %macro LOAD_ADD 3
35     movd        %1,     %2
36     movd        mm7,    %3
37     punpcklbw   %1,     mm0
38     punpcklbw   mm7,    mm0
39     paddw       %1,     mm7
40 %endmacro
41
42 %macro FILT_V 0
43     psubw       mm1,    mm2         ; a-b
44     psubw       mm4,    mm5
45     psubw       mm2,    mm3         ; b-c
46     psubw       mm5,    mm6
47     psllw       mm2,    2
48     psllw       mm5,    2
49     psubw       mm1,    mm2         ; a-5*b+4*c
50     psubw       mm4,    mm5
51     psllw       mm3,    4
52     psllw       mm6,    4
53     paddw       mm1,    mm3         ; a-5*b+20*c
54     paddw       mm4,    mm6
55 %endmacro
56
57 %macro FILT_H 0
58     psubw       mm1,    mm2         ; a-b
59     psubw       mm4,    mm5
60     psraw       mm1,    2           ; (a-b)/4
61     psraw       mm4,    2
62     psubw       mm1,    mm2         ; (a-b)/4-b
63     psubw       mm4,    mm5
64     paddw       mm1,    mm3         ; (a-b)/4-b+c
65     paddw       mm4,    mm6
66     psraw       mm1,    2           ; ((a-b)/4-b+c)/4
67     psraw       mm4,    2
68     paddw       mm1,    mm3         ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
69     paddw       mm4,    mm6
70 %endmacro
71
72 %macro FILT_PACK 1
73     paddw       mm1,    mm7
74     paddw       mm4,    mm7
75     psraw       mm1,    %1
76     psraw       mm4,    %1
77     packuswb    mm1,    mm4
78 %endmacro
79
80 ;-----------------------------------------------------------------------------
81 ; void x264_hpel_filter_mmxext( uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src,
82 ;                               int i_stride, int i_width, int i_height );
83 ;-----------------------------------------------------------------------------
84 cglobal x264_hpel_filter_mmxext, 0,7
85     %define     x       r0
86     %define     xd      r0d
87     %define     dsth    r1
88     %define     dstv    r1
89     %define     dstc    r1
90     %define     src     r2
91     %define     src3    r3
92     %define     stride  r4
93     %define     width   r5d
94     %define     tbuffer rsp+8
95
96 %ifdef ARCH_X86_64
97     PUSH        rbp
98     PUSH        r12
99     PUSH        r13
100     PUSH        r14
101     %define     tdsth   r10 ; FIXME r8,9
102     %define     tdstv   r11
103     %define     tdstc   r12
104     %define     tsrc    r13
105     %define     theight r14d
106     mov         tdsth,  r0
107     mov         tdstv,  r1
108     mov         tdstc,  r2
109     mov         tsrc,   r3
110     mov         theight, r6m
111 %else
112     %define     tdsth   [rbp + 20]
113     %define     tdstv   [rbp + 24]
114     %define     tdstc   [rbp + 28]
115     %define     tsrc    [rbp + 32]
116     %define     theight [rbp + 44]
117 %endif
118
119     movifnidn   r4d,    r4m
120     movifnidn   r5d,    r5m
121     mov         rbp,    rsp
122     lea         rax,    [stride*2 + 24]
123     sub         rsp,    rax
124     pxor        mm0,    mm0
125
126     %define     tpw_1   [pw_1 GLOBAL]
127     %define     tpw_16  [pw_16 GLOBAL]
128     %define     tpw_32  [pw_32 GLOBAL]
129 %ifdef PIC32
130     ; mov globals onto the stack, to free up PIC pointer
131     %define     tpw_1   [ebp - 24]
132     %define     tpw_16  [ebp - 16]
133     %define     tpw_32  [ebp -  8]
134     picgetgot   ebx
135     sub         esp,    24
136     movq        mm1,    [pw_1  GLOBAL]
137     movq        mm2,    [pw_16 GLOBAL]
138     movq        mm3,    [pw_32 GLOBAL]
139     movq        tpw_1,  mm1
140     movq        tpw_16, mm2
141     movq        tpw_32, mm3
142 %endif
143
144 .loopy:
145
146     mov         src,    tsrc
147     mov         dstv,   tdstv
148     lea         src3,   [src + stride]
149     sub         src,    stride
150     sub         src,    stride
151     xor         xd,     xd
152 ALIGN 16
153 .vertical_filter:
154
155     prefetcht0  [src3 + stride*2 + 32]
156
157     LOAD_ADD    mm1,    [src               ], [src3 + stride*2    ] ; a0
158     LOAD_ADD    mm2,    [src + stride      ], [src3 + stride      ] ; b0
159     LOAD_ADD    mm3,    [src + stride*2    ], [src3               ] ; c0
160     LOAD_ADD    mm4,    [src            + 4], [src3 + stride*2 + 4] ; a1
161     LOAD_ADD    mm5,    [src + stride   + 4], [src3 + stride   + 4] ; b1
162     LOAD_ADD    mm6,    [src + stride*2 + 4], [src3            + 4] ; c1
163
164     FILT_V
165
166     movq        mm7,    tpw_16
167     movq        [tbuffer + x*2],  mm1
168     movq        [tbuffer + x*2 + 8],  mm4
169     paddw       mm1,    mm7
170     paddw       mm4,    mm7
171     psraw       mm1,    5
172     psraw       mm4,    5
173     packuswb    mm1,    mm4
174     movntq      [dstv + x], mm1
175
176     add         xd,     8
177     add         src,    8
178     add         src3,   8
179     cmp         xd,     width
180     jle         .vertical_filter
181
182     pshufw      mm2, [tbuffer], 0
183     movq        [tbuffer - 8], mm2 ; pad left
184     ; no need to pad right, since vertical_filter already did 4 extra pixels
185
186     mov         dstc,   tdstc
187     xor         xd,     xd
188     movq        mm7,    tpw_32
189 .center_filter:
190
191     movq        mm1,    [tbuffer + x*2 - 4 ]
192     movq        mm2,    [tbuffer + x*2 - 2 ]
193     movq        mm3,    [tbuffer + x*2     ]
194     movq        mm4,    [tbuffer + x*2 + 4 ]
195     movq        mm5,    [tbuffer + x*2 + 6 ]
196     paddw       mm3,    [tbuffer + x*2 + 2 ] ; c0
197     paddw       mm2,    mm4                  ; b0
198     paddw       mm1,    mm5                  ; a0
199     movq        mm6,    [tbuffer + x*2 + 8 ]
200     paddw       mm4,    [tbuffer + x*2 + 14] ; a1
201     paddw       mm5,    [tbuffer + x*2 + 12] ; b1
202     paddw       mm6,    [tbuffer + x*2 + 10] ; c1
203
204     FILT_H
205     FILT_PACK 6
206     movntq      [dstc + x], mm1
207
208     add         xd,     8
209     cmp         xd,     width
210     jl          .center_filter
211
212     mov         dsth,   tdsth
213     mov         src,    tsrc
214     xor         xd,     xd
215 .horizontal_filter:
216
217     movd        mm1,    [src + x - 2]
218     movd        mm2,    [src + x - 1]
219     movd        mm3,    [src + x    ]
220     movd        mm6,    [src + x + 1]
221     movd        mm4,    [src + x + 2]
222     movd        mm5,    [src + x + 3]
223     punpcklbw   mm1,    mm0
224     punpcklbw   mm2,    mm0
225     punpcklbw   mm3,    mm0
226     punpcklbw   mm6,    mm0
227     punpcklbw   mm4,    mm0
228     punpcklbw   mm5,    mm0
229     paddw       mm3,    mm6 ; c0
230     paddw       mm2,    mm4 ; b0
231     paddw       mm1,    mm5 ; a0
232     movd        mm7,    [src + x + 7]
233     movd        mm6,    [src + x + 6]
234     punpcklbw   mm7,    mm0
235     punpcklbw   mm6,    mm0
236     paddw       mm4,    mm7 ; c1
237     paddw       mm5,    mm6 ; b1
238     movd        mm7,    [src + x + 5]
239     movd        mm6,    [src + x + 4]
240     punpcklbw   mm7,    mm0
241     punpcklbw   mm6,    mm0
242     paddw       mm6,    mm7 ; a1
243
244     movq        mm7,    tpw_1
245     FILT_H
246     FILT_PACK 1
247     movntq      [dsth + x], mm1
248
249     add         xd,     8
250     cmp         xd,     width
251     jl          .horizontal_filter
252
253     add         tsrc,  stride
254     add         tdsth, stride
255     add         tdstv, stride
256     add         tdstc, stride
257     dec         dword theight
258     jg          .loopy
259
260     mov         rsp,    rbp
261 %ifdef ARCH_X86_64
262     pop         r14
263     pop         r13
264     pop         r12
265     pop         rbp
266 %endif
267     RET
268
269
270
271 ;-----------------------------------------------------------------------------
272 ; void x264_plane_copy_mmxext( uint8_t *dst, int i_dst,
273 ;                              uint8_t *src, int i_src, int w, int h)
274 ;-----------------------------------------------------------------------------
275 cglobal x264_plane_copy_mmxext, 6,7
276     movsxdifnidn r1, r1d
277     movsxdifnidn r3, r3d
278     add    r4d, 3
279     and    r4d, ~3
280     mov    r6d, r4d
281     and    r6d, ~15
282     sub    r1,  r6
283     sub    r3,  r6
284 .loopy:
285     mov    r6d, r4d
286     sub    r6d, 64
287     jl     .endx
288 .loopx:
289     prefetchnta [r2+256]
290     movq   mm0, [r2   ]
291     movq   mm1, [r2+ 8]
292     movq   mm2, [r2+16]
293     movq   mm3, [r2+24]
294     movq   mm4, [r2+32]
295     movq   mm5, [r2+40]
296     movq   mm6, [r2+48]
297     movq   mm7, [r2+56]
298     movntq [r0   ], mm0
299     movntq [r0+ 8], mm1
300     movntq [r0+16], mm2
301     movntq [r0+24], mm3
302     movntq [r0+32], mm4
303     movntq [r0+40], mm5
304     movntq [r0+48], mm6
305     movntq [r0+56], mm7
306     add    r2,  64
307     add    r0,  64
308     sub    r6d, 64
309     jge    .loopx
310 .endx:
311     prefetchnta [r2+256]
312     add    r6d, 48
313     jl .end16
314 .loop16:
315     movq   mm0, [r2  ]
316     movq   mm1, [r2+8]
317     movntq [r0  ], mm0
318     movntq [r0+8], mm1
319     add    r2,  16
320     add    r0,  16
321     sub    r6d, 16
322     jge    .loop16
323 .end16:
324     add    r6d, 12
325     jl .end4
326 .loop4:
327     movd   mm2, [r2+r6]
328     movd   [r0+r6], mm2
329     sub    r6d, 4
330     jge .loop4
331 .end4:
332     add    r2, r3
333     add    r0, r1
334     dec    r5d
335     jg     .loopy
336     emms
337     RET
338
339 ;-----------------------------------------------------------------------------
340 ; void *x264_memcpy_aligned_mmx( void *dst, const void *src, size_t n );
341 ;-----------------------------------------------------------------------------
342 cglobal x264_memcpy_aligned_mmx, 3,3
343     test r2d, 16
344     jz .copy32
345     sub r2d, 16
346     movq mm0, [r1 + r2 + 0]
347     movq mm1, [r1 + r2 + 8]
348     movq [r0 + r2 + 0], mm0
349     movq [r0 + r2 + 8], mm1
350 .copy32:
351         sub r2d, 32
352         movq mm0, [r1 + r2 +  0]
353         movq mm1, [r1 + r2 +  8]
354         movq mm2, [r1 + r2 + 16]
355         movq mm3, [r1 + r2 + 24]
356         movq [r0 + r2 +  0], mm0
357         movq [r0 + r2 +  8], mm1
358         movq [r0 + r2 + 16], mm2
359         movq [r0 + r2 + 24], mm3
360     jg .copy32
361     REP_RET
362
363 ;-----------------------------------------------------------------------------
364 ; void *x264_memcpy_aligned_sse2( void *dst, const void *src, size_t n );
365 ;-----------------------------------------------------------------------------
366 cglobal x264_memcpy_aligned_sse2, 3,3
367     test r2d, 16
368     jz .copy32
369     sub r2d, 16
370     movdqa xmm0, [r1 + r2]
371     movdqa [r0 + r2], xmm0
372 .copy32:
373     test r2d, 32
374     jz .copy64
375     sub r2d, 32
376     movdqa xmm0, [r1 + r2 +  0]
377     movdqa xmm1, [r1 + r2 + 16]
378     movdqa [r0 + r2 +  0], xmm0
379     movdqa [r0 + r2 + 16], xmm1
380 .copy64:
381         sub r2d, 64
382         movdqa xmm0, [r1 + r2 +  0]
383         movdqa xmm1, [r1 + r2 + 16]
384         movdqa xmm2, [r1 + r2 + 32]
385         movdqa xmm3, [r1 + r2 + 48]
386         movdqa [r0 + r2 +  0], xmm0
387         movdqa [r0 + r2 + 16], xmm1
388         movdqa [r0 + r2 + 32], xmm2
389         movdqa [r0 + r2 + 48], xmm3
390     jg .copy64
391     REP_RET