1/*
2 * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
3 *
4 * This file is part of Libav.
5 *
6 * Libav is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * Libav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "asm.S"
22
23        preserve8
24
25function ff_h264_idct_add_neon, export=1
26        vld1.64         {d0-d3},  [r1,:128]
27
28        vswp            d1,  d2
29        vadd.i16        d4,  d0,  d1
30        vshr.s16        q8,  q1,  #1
31        vsub.i16        d5,  d0,  d1
32        vadd.i16        d6,  d2,  d17
33        vsub.i16        d7,  d16, d3
34        vadd.i16        q0,  q2,  q3
35        vsub.i16        q1,  q2,  q3
36
37        vtrn.16         d0,  d1
38        vtrn.16         d3,  d2
39        vtrn.32         d0,  d3
40        vtrn.32         d1,  d2
41
42        vadd.i16        d4,  d0,  d3
43        vld1.32         {d18[0]}, [r0,:32], r2
44        vswp            d1,  d3
45        vshr.s16        q8,  q1,  #1
46        vld1.32         {d19[1]}, [r0,:32], r2
47        vsub.i16        d5,  d0,  d1
48        vld1.32         {d18[1]}, [r0,:32], r2
49        vadd.i16        d6,  d16, d3
50        vld1.32         {d19[0]}, [r0,:32], r2
51        vsub.i16        d7,  d2,  d17
52        sub             r0,  r0,  r2, lsl #2
53        vadd.i16        q0,  q2,  q3
54        vsub.i16        q1,  q2,  q3
55
56        vrshr.s16       q0,  q0,  #6
57        vrshr.s16       q1,  q1,  #6
58
59        vaddw.u8        q0,  q0,  d18
60        vaddw.u8        q1,  q1,  d19
61
62        vqmovun.s16     d0,  q0
63        vqmovun.s16     d1,  q1
64
65        vst1.32         {d0[0]},  [r0,:32], r2
66        vst1.32         {d1[1]},  [r0,:32], r2
67        vst1.32         {d0[1]},  [r0,:32], r2
68        vst1.32         {d1[0]},  [r0,:32], r2
69
70        bx              lr
71endfunc
72
73function ff_h264_idct_dc_add_neon, export=1
74        vld1.16         {d2[],d3[]}, [r1,:16]
75        vrshr.s16       q1,  q1,  #6
76        vld1.32         {d0[0]},  [r0,:32], r2
77        vld1.32         {d0[1]},  [r0,:32], r2
78        vaddw.u8        q2,  q1,  d0
79        vld1.32         {d1[0]},  [r0,:32], r2
80        vld1.32         {d1[1]},  [r0,:32], r2
81        vaddw.u8        q1,  q1,  d1
82        vqmovun.s16     d0,  q2
83        vqmovun.s16     d1,  q1
84        sub             r0,  r0,  r2, lsl #2
85        vst1.32         {d0[0]},  [r0,:32], r2
86        vst1.32         {d0[1]},  [r0,:32], r2
87        vst1.32         {d1[0]},  [r0,:32], r2
88        vst1.32         {d1[1]},  [r0,:32], r2
89        bx              lr
90endfunc
91
92function ff_h264_idct_add16_neon, export=1
93        push            {r4-r8,lr}
94        mov             r4,  r0
95        mov             r5,  r1
96        mov             r1,  r2
97        mov             r2,  r3
98        ldr             r6,  [sp, #24]
99        movrel          r7,  scan8
100        mov             ip,  #16
1011:      ldrb            r8,  [r7], #1
102        ldr             r0,  [r5], #4
103        ldrb            r8,  [r6, r8]
104        subs            r8,  r8,  #1
105        blt             2f
106        ldrsh           lr,  [r1]
107        add             r0,  r0,  r4
108        it              ne
109        movne           lr,  #0
110        cmp             lr,  #0
111        ite             ne
112        adrne           lr,  ff_h264_idct_dc_add_neon + CONFIG_THUMB
113        adreq           lr,  ff_h264_idct_add_neon    + CONFIG_THUMB
114        blx             lr
1152:      subs            ip,  ip,  #1
116        add             r1,  r1,  #32
117        bne             1b
118        pop             {r4-r8,pc}
119endfunc
120
121function ff_h264_idct_add16intra_neon, export=1
122        push            {r4-r8,lr}
123        mov             r4,  r0
124        mov             r5,  r1
125        mov             r1,  r2
126        mov             r2,  r3
127        ldr             r6,  [sp, #24]
128        movrel          r7,  scan8
129        mov             ip,  #16
1301:      ldrb            r8,  [r7], #1
131        ldr             r0,  [r5], #4
132        ldrb            r8,  [r6, r8]
133        add             r0,  r0,  r4
134        cmp             r8,  #0
135        ldrsh           r8,  [r1]
136        iteet           ne
137        adrne           lr,  ff_h264_idct_add_neon    + CONFIG_THUMB
138        adreq           lr,  ff_h264_idct_dc_add_neon + CONFIG_THUMB
139        cmpeq           r8,  #0
140        blxne           lr
141        subs            ip,  ip,  #1
142        add             r1,  r1,  #32
143        bne             1b
144        pop             {r4-r8,pc}
145endfunc
146
147function ff_h264_idct_add8_neon, export=1
148        push            {r4-r10,lr}
149        ldm             r0,  {r4,r9}
150        add             r5,  r1,  #16*4
151        add             r1,  r2,  #16*32
152        mov             r2,  r3
153        mov             r3,  r1
154        ldr             r6,  [sp, #32]
155        movrel          r7,  scan8+16
156        mov             r12, #0
1571:      ldrb            r8,  [r7, r12]
158        ldr             r0,  [r5, r12, lsl #2]
159        ldrb            r8,  [r6, r8]
160        add             r0,  r0,  r4
161        add             r1,  r3,  r12, lsl #5
162        cmp             r8,  #0
163        ldrsh           r8,  [r1]
164        iteet           ne
165        adrne           lr,  ff_h264_idct_add_neon    + CONFIG_THUMB
166        adreq           lr,  ff_h264_idct_dc_add_neon + CONFIG_THUMB
167        cmpeq           r8,  #0
168        blxne           lr
169        add             r12, r12, #1
170        cmp             r12, #4
171        itt             eq
172        moveq           r12, #16
173        moveq           r4,  r9
174        cmp             r12, #20
175        blt             1b
176        pop             {r4-r10,pc}
177endfunc
178
179.macro  idct8x8_cols    pass
180  .if \pass == 0
181        qa      .req    q2
182        qb      .req    q14
183        vshr.s16        q2,  q10, #1
184        vadd.i16        q0,  q8,  q12
185        vld1.16         {q14-q15},[r1,:128]!
186        vsub.i16        q1,  q8,  q12
187        vshr.s16        q3,  q14, #1
188        vsub.i16        q2,  q2,  q14
189        vadd.i16        q3,  q3,  q10
190  .else
191        qa      .req    q14
192        qb      .req    q2
193        vtrn.32         q8,  q10
194        vtrn.16         q12, q13
195        vtrn.32         q9,  q11
196        vtrn.32         q12, q2
197        vtrn.32         q13, q15
198        vswp            d21, d4
199        vshr.s16        q14, q10, #1
200        vswp            d17, d24
201        vshr.s16        q3,  q2,  #1
202        vswp            d19, d26
203        vadd.i16        q0,  q8,  q12
204        vswp            d23, d30
205        vsub.i16        q1,  q8,  q12
206        vsub.i16        q14, q14, q2
207        vadd.i16        q3,  q3,  q10
208  .endif
209        vadd.i16        q10, q1,  qa
210        vsub.i16        q12, q1,  qa
211        vadd.i16        q8,  q0,  q3
212        vsub.i16        qb,  q0,  q3
213        vsub.i16        q0,  q13, q11
214        vadd.i16        q1,  q15, q9
215        vsub.i16        qa,  q15, q9
216        vadd.i16        q3,  q13, q11
217        vsub.i16        q0,  q0,  q15
218        vsub.i16        q1,  q1,  q11
219        vadd.i16        qa,  qa,  q13
220        vadd.i16        q3,  q3,  q9
221        vshr.s16        q9,  q9,  #1
222        vshr.s16        q11, q11, #1
223        vshr.s16        q13, q13, #1
224        vshr.s16        q15, q15, #1
225        vsub.i16        q0,  q0,  q15
226        vsub.i16        q1,  q1,  q11
227        vadd.i16        qa,  qa,  q13
228        vadd.i16        q3,  q3,  q9
229        vshr.s16        q9,  q0,  #2
230        vshr.s16        q11, q1,  #2
231        vshr.s16        q13, qa,  #2
232        vshr.s16        q15, q3,  #2
233        vsub.i16        q3,  q3,  q9
234        vsub.i16        qa,  q11, qa
235        vadd.i16        q1,  q1,  q13
236        vadd.i16        q0,  q0,  q15
237  .if \pass == 0
238        vsub.i16        q15, q8,  q3
239        vadd.i16        q8,  q8,  q3
240        vadd.i16        q9,  q10, q2
241        vsub.i16        q2,  q10, q2
242        vtrn.16         q8,  q9
243        vadd.i16        q10, q12, q1
244        vtrn.16         q2,  q15
245        vadd.i16        q11, q14, q0
246        vsub.i16        q13, q12, q1
247        vtrn.16         q10, q11
248        vsub.i16        q12, q14, q0
249  .else
250        vsub.i16        q15, q8,  q3
251        vadd.i16        q8,  q8,  q3
252        vadd.i16        q9,  q10, q14
253        vsub.i16        q14, q10, q14
254        vadd.i16        q10, q12, q1
255        vsub.i16        q13, q12, q1
256        vadd.i16        q11, q2, q0
257        vsub.i16        q12, q2, q0
258  .endif
259        .unreq          qa
260        .unreq          qb
261.endm
262
263function ff_h264_idct8_add_neon, export=1
264        vld1.16         {q8-q9},  [r1,:128]!
265        vld1.16         {q10-q11},[r1,:128]!
266        vld1.16         {q12-q13},[r1,:128]!
267
268        idct8x8_cols    0
269        idct8x8_cols    1
270
271        mov             r3,  r0
272        vrshr.s16       q8,  q8,  #6
273        vld1.8          {d0},     [r0,:64], r2
274        vrshr.s16       q9,  q9,  #6
275        vld1.8          {d1},     [r0,:64], r2
276        vrshr.s16       q10, q10, #6
277        vld1.8          {d2},     [r0,:64], r2
278        vrshr.s16       q11, q11, #6
279        vld1.8          {d3},     [r0,:64], r2
280        vrshr.s16       q12, q12, #6
281        vld1.8          {d4},     [r0,:64], r2
282        vrshr.s16       q13, q13, #6
283        vld1.8          {d5},     [r0,:64], r2
284        vrshr.s16       q14, q14, #6
285        vld1.8          {d6},     [r0,:64], r2
286        vrshr.s16       q15, q15, #6
287        vld1.8          {d7},     [r0,:64], r2
288        vaddw.u8        q8,  q8,  d0
289        vaddw.u8        q9,  q9,  d1
290        vaddw.u8        q10, q10, d2
291        vqmovun.s16     d0,  q8
292        vaddw.u8        q11, q11, d3
293        vqmovun.s16     d1,  q9
294        vaddw.u8        q12, q12, d4
295        vqmovun.s16     d2,  q10
296        vst1.8          {d0},     [r3,:64], r2
297        vaddw.u8        q13, q13, d5
298        vqmovun.s16     d3,  q11
299        vst1.8          {d1},     [r3,:64], r2
300        vaddw.u8        q14, q14, d6
301        vqmovun.s16     d4,  q12
302        vst1.8          {d2},     [r3,:64], r2
303        vaddw.u8        q15, q15, d7
304        vqmovun.s16     d5,  q13
305        vst1.8          {d3},     [r3,:64], r2
306        vqmovun.s16     d6,  q14
307        vqmovun.s16     d7,  q15
308        vst1.8          {d4},     [r3,:64], r2
309        vst1.8          {d5},     [r3,:64], r2
310        vst1.8          {d6},     [r3,:64], r2
311        vst1.8          {d7},     [r3,:64], r2
312
313        sub             r1,  r1,  #128
314        bx              lr
315endfunc
316
317function ff_h264_idct8_dc_add_neon, export=1
318        vld1.16         {d30[],d31[]},[r1,:16]
319        vld1.32         {d0},     [r0,:64], r2
320        vrshr.s16       q15, q15, #6
321        vld1.32         {d1},     [r0,:64], r2
322        vld1.32         {d2},     [r0,:64], r2
323        vaddw.u8        q8,  q15, d0
324        vld1.32         {d3},     [r0,:64], r2
325        vaddw.u8        q9,  q15, d1
326        vld1.32         {d4},     [r0,:64], r2
327        vaddw.u8        q10, q15, d2
328        vld1.32         {d5},     [r0,:64], r2
329        vaddw.u8        q11, q15, d3
330        vld1.32         {d6},     [r0,:64], r2
331        vaddw.u8        q12, q15, d4
332        vld1.32         {d7},     [r0,:64], r2
333        vaddw.u8        q13, q15, d5
334        vaddw.u8        q14, q15, d6
335        vaddw.u8        q15, q15, d7
336        vqmovun.s16     d0,  q8
337        vqmovun.s16     d1,  q9
338        vqmovun.s16     d2,  q10
339        vqmovun.s16     d3,  q11
340        sub             r0,  r0,  r2, lsl #3
341        vst1.32         {d0},     [r0,:64], r2
342        vqmovun.s16     d4,  q12
343        vst1.32         {d1},     [r0,:64], r2
344        vqmovun.s16     d5,  q13
345        vst1.32         {d2},     [r0,:64], r2
346        vqmovun.s16     d6,  q14
347        vst1.32         {d3},     [r0,:64], r2
348        vqmovun.s16     d7,  q15
349        vst1.32         {d4},     [r0,:64], r2
350        vst1.32         {d5},     [r0,:64], r2
351        vst1.32         {d6},     [r0,:64], r2
352        vst1.32         {d7},     [r0,:64], r2
353        bx              lr
354endfunc
355
356function ff_h264_idct8_add4_neon, export=1
357        push            {r4-r8,lr}
358        mov             r4,  r0
359        mov             r5,  r1
360        mov             r1,  r2
361        mov             r2,  r3
362        ldr             r6,  [sp, #24]
363        movrel          r7,  scan8
364        mov             r12, #16
3651:      ldrb            r8,  [r7], #4
366        ldr             r0,  [r5], #16
367        ldrb            r8,  [r6, r8]
368        subs            r8,  r8,  #1
369        blt             2f
370        ldrsh           lr,  [r1]
371        add             r0,  r0,  r4
372        it              ne
373        movne           lr,  #0
374        cmp             lr,  #0
375        ite             ne
376        adrne           lr,  ff_h264_idct8_dc_add_neon + CONFIG_THUMB
377        adreq           lr,  ff_h264_idct8_add_neon    + CONFIG_THUMB
378        blx             lr
3792:      subs            r12, r12, #4
380        add             r1,  r1,  #128
381        bne             1b
382        pop             {r4-r8,pc}
383endfunc
384
385const   scan8
386        .byte           4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
387        .byte           6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
388        .byte           4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
389        .byte           6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8
390        .byte           4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8
391        .byte           6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8
392        .byte           4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8
393        .byte           6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8
394        .byte           4+11*8, 5+11*8, 4+12*8, 5+12*8
395        .byte           6+11*8, 7+11*8, 6+12*8, 7+12*8
396        .byte           4+13*8, 5+13*8, 4+14*8, 5+14*8
397        .byte           6+13*8, 7+13*8, 6+14*8, 7+14*8
398endconst
399